waves/public/assets/g/box/index.html
2025-04-09 17:11:14 -05:00

16805 lines
629 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Sandboxels - Experiment with Pixels</title>
<meta name="description" content="Relax or experiment with over 500 materials in this falling sand simulator, featuring heat, chemical reactions, density, burning, explosions.">
<meta name="keywords" content="falling sand, elements, pixel art, simulator, powder, toy, chemistry, science, educational">
<meta name="author" content="R74n">
<script src="./js/all.min.js"></script>
<meta name="copyright" content="R74n">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="all">
<meta name="contact" content="contact@R74n.com">
<style>
@import url('https://fonts.cdnfonts.com/css/times-new-roman');
html, body {
width: 100%;
height: 100%;
margin: 0;
}
body {
font-family: TImes New Roman, serif;
background-color: #ff00ff;
color: #00ff00;
}
* {
font-family: TImes New Roman, serif !important;
background-color: #ff00ff !important;
color: #00ff00 !important;
}
.pagetitle {
padding: 10px;
padding-bottom: 0px;
font-size: 0.75em;
position: absolute;
top: 0;
left: 0;
}
a, .saveOption {color: rgb(255, 0, 255);text-decoration: none;}
a:hover, .saveOption:hover {filter: brightness(200%);}
a:active, a:hover:active, .saveOption:active, .saveOption:hover:active {filter: brightness(275%);}
#gameDiv { /*game canvas*/
border: 1px solid #ffffff;
position: relative;
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Old versions of Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none;
margin-top: 15px;
}
#game {
image-rendering: pixelated;
}
#bottomInfoBox { /* place under the game canvas */
margin: 1.5em 50px 0px 50px;
}
#bottomTopBox {
text-align: center;
}
#bottomLeftBox {
float: left;
width: 50%;
text-align: left;
}
#bottomRightBox {
float: right;
width: 50%;
text-align: right;
}
table {
border-collapse: collapse;
background-color: rgba(255, 255, 255, 0.125);
}
#controlsTable {
width: 75%;
margin-left: auto;
margin-right: 0px;
}
/* alternating table row colors */
tr:nth-child(even) {
background-color: rgba(255, 255, 255, 0.0625);
}
th, td {
text-align: left;
padding: 8px;
border: 1px solid #9f9f9f;
}
kbd {
/* Look like a button */
display: inline-block;
padding: 0.2em 0.6em 0.3em;
font-size: 90%;
font-weight: 700;
color: rgb(255, 255, 255);
background-color: rgb(95, 95, 95);
border-radius: 0.2em;
border: 1px solid #000;
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2), 0 0 0 2px rgba(0, 0, 0, 0.05);
font-family: 'Arial';
cursor: pointer;
}
kbd:active {filter: brightness(70%);}
#infoParent, #modParent, #settingsParent, .menuParent {
display: none;
}
#infoScreen, #modManager, #settingsMenu, .menuScreen {
position: absolute;
border: 1px solid #ffffff;
left: 50%;
top: 5%;
transform: translate(-50%, 0%);
width: 95%;
height: 50%;
max-width: 700px;
padding: 10px;
background-color: rgb(31, 31, 31);
overflow-x: hidden;
z-index: 10;
}
#settingsMenu {
height: 75%;
}
#infoSearch, #modManagerUrl, #saveButtons {
position: absolute;
bottom: 59.4%;
width: 95%;
max-width: 700px;
height: 50px;
left: 50%;
transform: translate(-50%, 198.5%);
background-color: rgb(66, 66, 66);
color: white;
font-size: 1.5em;
padding: 8px;
font-family: 'Press Start 2P';
z-index: 11;
}
#infoSearch:focus, #modManagerUrl:focus {
outline: none;
}
.menuTitle {
font-size: 1.5em;
text-decoration: underline;
}
.menuText {
margin-top: 5px;
line-height: 1.5em;
}
#infoText {
white-space: pre-wrap;
}
.XButton {
position: absolute;
right: 0px;
top: 0px;
font-size: 2em;
background-color: rgb(100, 33, 33);
padding:5px;
text-align:center;
border: 1px solid #ffffff;
z-index: 12;
}
.XButton:hover {
background-color: rgb(200, 33, 33);
}
/*#modManagerAdd {
position: absolute;
bottom: 25%;
right: 25%;
height: 50px;
width: 50px;
transform: translate(-25%, -25%);
background-color: rgb(0, 190, 32);
color: white;
font-size: 2em;
padding: 10px;
font-family: 'Press Start 2P';
}*/
#modManagerList {
margin-top: 20px;
}
#modManagerList li {
list-style-type: none;
position: relative;
}
#modManagerList li::before {
content: '•';
position: absolute;
left: -1.5em;
font-size: 1em;
font-family: 'Press Start 2P';
}
.removeModX {
color: red;
cursor: pointer;
}
.removeModX:hover {
color: rgb(255, 107, 107);
}
.infoLink {
color: rgb(116, 140, 221);
cursor: pointer;
text-decoration: underline;
}
.saveSlot {
display: block;
border-top: solid gray;
padding-top: 1em;
padding-bottom: 1em;
padding-left: 1em;
}
.saveSlot:last-child {
border-bottom: solid gray;
}
.saveOption {
float: right;
padding-left: 2em;
padding-right: 1em;
color: #ff00ff;
cursor: pointer;
}
.saveOption:first-child {
padding-right: 2em;
}
.saveOption[disabled="true"] {
color: gray;
cursor: not-allowed;
}
#saveFile, #loadFile, #saveConfirm {
background-color: black;
text-align: center;
vertical-align: middle;
height: 3em;
line-height: 3em;
position:absolute;
bottom: 0;
cursor: pointer;
border-top: solid white;
}
#saveFile {
left: 0;
width: 50%;
}
#loadFile {
right: 0;
width: 50%;
border-left: solid white;
}
#saveConfirm {
left: 0;
width: 100%;
}
button, input[type="submit"], input[type="reset"] {
background: none;
color: inherit;
border: none;
padding: 0;
font: inherit;
cursor: pointer;
}
.usingTab button:focus {
filter: brightness(75%);
outline: none;
}
#underBox {
position: relative;
left: 50%;
transform: translate(-50%, -0%);
margin-top: 10px;
width: 100%;
}
#controls button {
padding: 5px 10px;
border-radius: 5px;
font-size: 1em;
text-shadow: 0.5px 1px 4px #000000;
color: rgba(255, 255, 255, 0.85);
border: 1px solid #797979;
margin: 0px 5px 5px 5px;
font-variant: small-caps;
}
#controls button.bright {
text-shadow: 0.5px 1px 4px #ffffff;
color: rgba(0, 0, 0, 0.85);
}
/*Darken when active*/
#controls button:active, #controls button:active:hover {
filter: brightness(60%);
}
#controls button:hover {
filter: brightness(90%);
}
#controls button:disabled {
cursor: not-allowed;
}
#controls button[current="true"], #controls button[on="true"] {
border: 1px solid #ffffff;
filter: brightness(110%);
box-shadow: 0 5px 15px rgba(255, 255, 255, .4);
color: rgba(255, 255, 255, 1);
}
#controls .elementButton[current="true"] {
border: 1px solid #00ff00;
box-shadow: 0px 1px 15px rgba(0, 255, 0, .75);
}
#controls button.bright[current="true"] {
color: rgba(0, 0, 0, 1);
}
#controls button[on="true"] {
border-color:lime;
color:lime;
}
#controls div {
display:block;
}
.stat {
margin-right: 25px;
margin-bottom: 5px;
float:right;
}
#stats {
margin: 0px 5px 0px 5px;
font-size: 0.75em;
height: 1.5em;
width:100%;
/* no wrapping */
white-space: nowrap;
overflow-x: hidden;
}
/* screen size < 800px */
@media screen and (max-width: 800px) { /* Mobile Styles */
.pagetitle {
font-size: 1em;
padding-left: 0.25em;
}
#bottomLeftBox, #bottomRightBox {
width: 100%;
margin: 1px;
text-align: left;
}
table {
width: 100%;
margin-left: 0px;
margin-right: 0px;
}
#gameDiv { /*game canvas*/
margin-top: 0;
}
.stat {
margin-right: 15px;
margin-bottom: 3px;
}
#stats {
width: 97%;
margin-left: 5px;
font-size: 0.75em;
height: 2.5em
}
}
@media screen and (max-width: 600px) {
#gameDiv { /*game canvas*/
margin-top: 0;
border-left: none;
border-right: none;
border-top: none;
}
.pagetitle {
display: none
}
}
@media screen and (min-width: 800px) { /* Desktop-Only Styles */
#gameDiv {
width:800px;
left: 50%;
transform: translate(-50%, -0%);
}
}
/* screen size > 1325px, h1::after {content:" Sandboxels"} */
@media screen and (min-width: 1325px) {
.pagetitle::after {content:" Sandboxels"}
}
#stat-pos, #stat-pixels, #stat-shift, #stat-tps, #stat-ticks, #stat-view {
float:left;
}
#stat-view, #stat-element {
text-transform: uppercase;
}
.categoryName {
font-size: 0.75em;
text-transform: uppercase;
margin-left: 5px;
vertical-align: middle;
}
#extraInfo {
margin:5px
}
#toolControls, #category-tools {
white-space: nowrap;
overflow-x: auto;
overflow-y: hidden;
width: 100%;
}
/* Scrollbars */
#toolControls, #category-tools, #categoryControls, #elementControls {
scrollbar-color: rgba(255, 255, 255, 0.25) rgba(255, 255, 255, 0.1);
scrollbar-width: thin;
}
@media screen and (max-width: 700px) {
#toolControls, #category-tools, #categoryControls, #elementControls {
margin-bottom: 5px !important;
}
}
#toolControls::-webkit-scrollbar, #category-tools::-webkit-scrollbar, #categoryControls::-webkit-scrollbar, #elementControls::-webkit-scrollbar {
width: 5px;
height: 8px;
background-color: rgba(255, 255, 255, 0.15);
}
#toolControls::-webkit-scrollbar-thumb, #category-tools::-webkit-scrollbar-thumb, #categoryControls::-webkit-scrollbar-thumb, #elementControls::-webkit-scrollbar-thumb {
background-color: rgba(255, 255, 255, 0.25);
border-radius: 5px;
}
#toolControls::-webkit-scrollbar-track, #category-tools::-webkit-scrollbar-track, #categoryControls::-webkit-scrollbar-track, #elementControls::-webkit-scrollbar-track {
box-shadow: inset 0 0 5px rgba(255, 255, 255, 0.15);
border-radius: 10px;
}
#toolControls::-webkit-scrollbar-thumb:hover, #category-tools::-webkit-scrollbar-thumb:hover, #categoryControls::-webkit-scrollbar-thumb:hover, #elementControls::-webkit-scrollbar-thumb:hover {
background-color: rgba(255, 255, 255, 0.3);
}
#toolControls {
z-index: 3;
}
#category-tools {
z-index: 2;
}
#categoryControls {
margin-bottom: 5px;
background-color: rgba(255, 255, 255, 0.125);
white-space: nowrap;
overflow-x: auto;
overflow-y: hidden;
width: 100%;
position: relative;
z-index: 1;
padding-bottom:1px;
}
#categoryControls button {
/* Borderless buttons */
border: none;
border-radius: 0;
padding-right: 8px;
margin: 0;
padding-top: 5px;
padding-bottom: 5px;
display: inline-block;
position: relative;
z-index:0;
}
#categoryControls button:not(:last-child) {
border-right: 1px solid rgba(255, 255, 255, 0.4);
}
#categoryControls button[current="true"] {
border: none;
background-color: rgba(255, 255, 255, 0.4);
}
.category {
margin-top:0.75em;
position:relative;
display:flex;
flex-direction: column;
flex-wrap:wrap;
text-align:center;
}
button, input { /*Disable double tap zoom on mobile devices*/
touch-action: manipulation;
color-scheme: dark;
}
select, .toggleInput, #settingsMenu input[type="number"], #settingsMenu input[type="text"], #savePromptMenu input, input[type="email"] {
background-color: black;
vertical-align: middle;
margin-left: 5px;
margin-right: 5px;
border: rgb(150, 150, 150) 1px solid;
border-radius: 20px;
padding: 0.5em;
color: white;
font-size: 1em;
font-family: Arial, Helvetica, sans-serif;
}
#settingsMenu .toggleInput {
display: inline-block;
width: 4em;
text-align: center;
}
.toggleInput { cursor: pointer; }
.toggleInput[state="1"] {color: lime!important;}
.toggleInput[state="0"] {color: red!important;}
#settingsMenu input[type="number"] {
width: 3em;
}
.settingsButton {
background-color: black;
vertical-align: middle;
margin-left: 5px;
margin-right: 5px;
border: rgb(150, 150, 150) 1px solid;
border-radius: 20px;
padding: 0.5em;
color: white;
font-family: Arial, Helvetica, sans-serif;
}
.settingsButton:active, .toggleInput:active {
filter: brightness(75%);
}
#canvasDiv {
position:relative;
overflow-x:hidden
}
#colorSelector {
position:absolute;
bottom:1em;
right:1em;
display: none;
}
.categoryButton.notify {
background-color: rgba(255, 0, 0, 0.25);
}
/* .elementButton.notify with a red glow */
.elementButton.notify {
-webkit-box-shadow: 0px 0px 15px 5px #FF0000;
box-shadow: 0px 0px 15px 5px #FF0000;
}
.noselect {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently supported by Chrome and Opera */
}
.setting-span {
display:block;padding-bottom:0.5em
}
.multisetting {
display: inline-block
}
.helpMark {text-decoration:dotted underline; font-style:italic; cursor:help; color:yellow}
#content {
margin-left:10px;
margin-right:10px;
padding-bottom: 10px;
}
#logDiv {
position: absolute;
top: 0px;
left: 0px;
pointer-events: none;
padding: 5px;
white-space: pre-wrap;
font-size: 0.75em;
}
</style>
<!--Favicons-->
<link rel="apple-touch-icon" sizes="180x180" href="icons/apple-touch-icon.png?v=2">
<link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png?v=2">
<link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png?v=2">
<link rel="manifest" href="manifest.json">
<link rel="mask-icon" href="icons/safari-pinned-tab.svg?v=2" color="#2167ff">
<link rel="shortcut icon" href="icons/favicon.ico?v=2">
<link rel="help" href="https://sandboxels.R74n.com/help">
<link rel="search" href="https://R74n.com/search/#gsc.tab=0">
<link rel="license" href="https://sandboxels.R74n.com/license.txt">
<meta name="msapplication-TileColor" content="#e6d577">
<meta name="theme-color" content="#000000">
<!--OpenGraph-->
<meta property="og:locale" content="en_US">
<meta property="og:type" content="website">
<meta property="og:title" content="Sandboxels - Experiment with Pixels">
<meta property="og:description" content="Relax or experiment with over 500 materials in this falling sand simulator.">
<meta property="og:url" content="https://sandboxels.r74n.com">
<meta property="og:site_name" content="Sandboxels">
<meta property="og:image" content="https://sandboxels.r74n.com/icons/wallpaper.png">
<meta property="og:image:width" content="1980">
<meta property="og:image:height" content="971">
<meta property="og:image:type" content="image/png">
<meta property="og:image:alt" content="A rainforest made in Sandboxels">
<!--Twitter-->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:description" content="Relax or experiment with over 500 materials in this falling sand simulator.">
<meta name="twitter:title" content="Sandboxels - Experiment with Pixels">
<meta name="twitter:site:id" content="1436857621827530753">
<meta name="twitter:image" content="https://sandboxels.r74n.com/icons/card.png">
<meta name="twitter:image:alt" content="A rainforest made in Sandboxels">
<meta name="twitter:creator:id" content="1436857621827530753">
<script> // versioning info
currentversion = "1.9.4.1";
saveVersion = 2;
</script>
<style>
.setting-span {
display:block;padding-bottom:0.5em
}
</style>
<!-- Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": ["VideoGame","MobileApplication","WebApplication"],
"gamePlatform":"Web Browser",
"image":"https://sandboxels.r74n.com/icons/icon.png",
"url": "https://sandboxels.r74n.com",
"name":"Sandboxels",
"author":"R74n",
"creator":"R74n",
"description":"Sandboxels is an in-browser falling sand simulator, with mechanics such as heat simulation, electricity, density, chemical reactions, fire, and over 500 unique elements to play with.",
"offers":{
"@type":"Offer",
"price":"0",
"priceCurrency":"USD",
"availability":"https://schema.org/InStock"
},
"genre": "Falling-sand game",
"softwareVersion":"1.9.1",
"datePublished":"2021-12-15",
"dateCreated":"2021-12-15",
"gameTip":"https://sandboxels.r74n.com/controls",
"softwareHelp":"https://sandboxels.r74n.com/controls",
"releaseNotes":"https://sandboxels.r74n.com/changelog",
"screenshot": "https://sandboxels.r74n.com/icons/wallpaper.png",
"softwareRequirements": "HTML5",
"archivedAt": "https://web.archive.org/web/20230519005427/https://sandboxels.r74n.com/",
"copyrightYear": 2024,
"copyrightNotice": "©2021-2024. All Rights Reserved. R74n",
"license": "https://sandboxels.r74n.com/license.txt",
"discussionUrl": "https://link.r74n.com/discord",
"educationalUse": "Hands-on lab experiments and learning",
"headline": "Sandboxels",
"isAccessibleForFree": true,
"isFamilyFriendly": true
}</script>
<script>
// replaceAll polyfill
if (!String.prototype.replaceAll) {String.prototype.replaceAll = function(str, newStr){if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]') {return this.replace(str, newStr);}return this.replace(new RegExp(str, 'g'), newStr);};}
// requestFullScreen
function requestFullScreen(element) { /* Supports most browsers and their versions.*/ var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen; if (requestMethod) { /*Native full screen.*/ requestMethod.call(element); } else if (typeof window.ActiveXObject !== "undefined") { /*Older IE.*/ var wscript = new ActiveXObject("WScript.Shell"); if (wscript !== null) { wscript.SendKeys("{F11}"); } } }
</script>
<script> // PWA things
// add service worker service-worker.js
if (typeof navigator !== 'undefined') {
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/service-worker.js');
});
}
}
</script>
<script>
console.log("%c WELCOME TO R74n ","position: absolute; top: 50%; right: 50%; transform: translate(50%,-50%); font-family: Arial; font-size: 3em; font-weight: 700; color: #00ffff; text-shadow: 1px 1px 1px #14c9c9, 1px 2px 1px #14c9c9, 1px 3px 1px #14c9c9, 1px 4px 1px #14c9c9, 1px 5px 1px #14c9c9, 1px 13px 6px rgba(16,16,16,0.4), 1px 22px 10px rgba(16,16,16,0.2), 1px 25px 35px rgba(16,16,16,0.2), 1px 30px 60px rgba(16,16,16,0.4);padding:10px");
console.log("Sandboxels is developed by R74n and can be played on the official website: https://sandboxels.R74n.com/");
console.log("Can't access? Join our Discord: https://link.R74n.com/discord");
console.log("Found this on another website? Let us know!");
console.log("©2021-" + new Date().getFullYear() + ". All Rights Reserved. https://sandboxels.R74n.com/license.txt");
// If settings is in localStorage, load it. If not, create an empty object.
settings = localStorage.getItem("settings") ? JSON.parse(localStorage.getItem("settings")) : {};
// URL query handling
var urlParams = new URLSearchParams(window.location.search);
if (urlParams.has("worldgen")) {
settings.worldgen = urlParams.get("worldgen");
}
if (!settings["unlocked"]) {
settings["unlocked"] = {};
}
function saveSettings() {
if (currentSaveData) { return }
localStorage.setItem("settings", JSON.stringify(settings));
}
defaultCooldown = 8;
behaviors = {
POWDER_OLD: [
"XX|XX|XX",
"XX|XX|XX",
"M2|M1|M2",
],
POWDER: function(pixel) {
if (pixel.start === pixelTicks) {return}
if (pixel.charge && elements[pixel.element].behaviorOn) {
pixelTick(pixel)
}
if (!tryMove(pixel, pixel.x, pixel.y+1)) {
if (Math.random() < 0.5) {
if (!tryMove(pixel, pixel.x+1, pixel.y+1)) {
tryMove(pixel, pixel.x-1, pixel.y+1);
}
} else {
if (!tryMove(pixel, pixel.x-1, pixel.y+1)) {
tryMove(pixel, pixel.x+1, pixel.y+1);
}
}
}
doDefaults(pixel);
},
AGPOWDER: [
"M2|M1|M2",
"XX|XX|XX",
"XX|XX|XX",
],
LIQUID_OLD: [
"XX|XX|XX",
"M2|XX|M2",
"M1|M1|M1",
],
LIQUID: function(pixel) {
if (pixel.start === pixelTicks) {return}
if (pixel.charge && elements[pixel.element].behaviorOn) {
pixelTick(pixel)
}
if (elements[pixel.element].viscosity && (!((Math.random()*100) < 100 / Math.pow(elements[pixel.element].viscosity, 0.25)))) {
var move1Spots = [
[pixel.x, pixel.y+1]
]
}
else {
var move1Spots = [
[pixel.x+1, pixel.y+1],
[pixel.x, pixel.y+1],
[pixel.x-1, pixel.y+1],
]
}
var moved = false;
for (var i = 0; i < move1Spots.length; i++) {
var coords = move1Spots[Math.floor(Math.random()*move1Spots.length)];
if (tryMove(pixel, coords[0], coords[1])) { moved = true; break; }
else { move1Spots.splice(move1Spots.indexOf(coords), 1); }
}
if (!moved) {
if (elements[pixel.element].viscosity===undefined || !(!((Math.random()*100) < 100 / Math.pow(elements[pixel.element].viscosity, 0.25)))) {
if (Math.random() < 0.5) {
if (!tryMove(pixel, pixel.x+1, pixel.y)) {
tryMove(pixel, pixel.x-1, pixel.y);
}
} else {
if (!tryMove(pixel, pixel.x-1, pixel.y)) {
tryMove(pixel, pixel.x+1, pixel.y);
}
}
}
}
doDefaults(pixel);
},
SUPERFLUID_OLD: [
"XX|XX|XX",
"XX|XX|M2 AND BO",
"XX|M1|M2",
],
SUPERFLUID: function(pixel) {
if (pixel.start === pixelTicks) {return}
if (pixel.charge && elements[pixel.element].behaviorOn) {
pixelTick(pixel)
}
if (!tryMove(pixel, pixel.x, pixel.y+1)) {
// go either left or right depending on pixel.flipX
var newx = pixel.flipX ? pixel.x-1 : pixel.x+1;
if (Math.random() < 0.5) {
if (!tryMove(pixel, newx, pixel.y)) {
pixel.flipX = !pixel.flipX;
tryMove(pixel, newx, pixel.y+1);
}
}
else {
if (!tryMove(pixel, newx, pixel.y+1)) {
if (!tryMove(pixel, newx, pixel.y)) { pixel.flipX = !pixel.flipX; }
}
}
}
doDefaults(pixel);
},
LIGHTWEIGHT: [
"XX|XX|XX",
"XX|FX%0.25|XX",
"M2%10|M1%10|M1%10",
],
SLIDE: [
"XX|XX|XX",
"XX|XX|M2 AND BO",
"XX|M1|M1",
],
AGLIQUID: [
"M1|M1|M1",
"M2|XX|M2",
"XX|XX|XX",
],
WALL: [
"XX|XX|XX",
"XX|XX|XX",
"XX|XX|XX",
],
UL_UR: [
"M1|M1|M1",
"M2|XX|M2",
"XX|M2|XX",
],
UL_UR_OPTIMIZED: function(pixel) {
if (pixel.start === pixelTicks) {return}
if (pixel.charge && elements[pixel.element].behaviorOn) {
pixelTick(pixel)
}
var move1Spots = [
[pixel.x, pixel.y-1],
[pixel.x+1, pixel.y-1],
[pixel.x-1, pixel.y-1],
]
var moved = false;
for (var i = 0; i < move1Spots.length; i++) {
var coords = move1Spots[Math.floor(Math.random()*move1Spots.length)];
if (tryMove(pixel, coords[0], coords[1])) { moved = true; break; }
else { move1Spots.splice(move1Spots.indexOf(coords), 1);}
}
if (!moved && !pixel.del) {
var move2Spots = [
[pixel.x, pixel.y+1],
[pixel.x+1, pixel.y],
[pixel.x-1, pixel.y],
]
for (var i = 0; i < move2Spots.length; i++) {
var coords = move2Spots[Math.floor(Math.random()*move2Spots.length)];
if (tryMove(pixel, coords[0], coords[1])) { break; }
else { move2Spots.splice(move2Spots.indexOf(coords), 1); }
}
}
if (!pixel.del) { doDefaults(pixel); }
},
GAS_OLD: [
"M2|M1|M2",
"M1|XX|M1",
"M2|M1|M2",
],
GAS: function(pixel) {
if (pixel.start === pixelTicks) {return}
if (pixel.charge && elements[pixel.element].behaviorOn) {
pixelTick(pixel)
}
var move1Spots = [
[pixel.x, pixel.y+1],
[pixel.x, pixel.y-1],
[pixel.x+1, pixel.y],
[pixel.x-1, pixel.y],
]
var moved = false;
for (var i = 0; i < move1Spots.length; i++) {
var coords = move1Spots[Math.floor(Math.random()*move1Spots.length)];
if (tryMove(pixel, coords[0], coords[1])) { moved = true; break; }
else { move1Spots.splice(move1Spots.indexOf(coords), 1);}
}
if (!moved) {
var move2Spots = [
[pixel.x+1, pixel.y+1],
[pixel.x-1, pixel.y+1],
[pixel.x+1, pixel.y-1],
[pixel.x-1, pixel.y-1],
]
for (var i = 0; i < move2Spots.length; i++) {
var coords = move2Spots[Math.floor(Math.random()*move2Spots.length)];
if (tryMove(pixel, coords[0], coords[1])) { break; }
else { move2Spots.splice(move2Spots.indexOf(coords), 1); }
}
}
doDefaults(pixel);
},
DGAS: [
"M2|M1|M2",
"M1|DL%5|M1",
"M2|M1|M2",
],
SUPPORT: [
"XX|XX|XX",
"SP|XX|SP",
"XX|M1|XX",
],
SUPPORTPOWDER: [
"XX|XX|XX",
"SP|XX|SP",
"M2|M1|M2",
],
DELETE: [
"XX|DL|XX",
"DL|XX|DL",
"XX|DL|XX",
],
FILL: [
"XX|CL|XX",
"CL|XX|CL",
"XX|CL|XX",
],
CLONER: [
"XX|CF|XX",
"CF|XX|CF",
"XX|CF|XX",
],
STURDYPOWDER: [
"XX|XX|XX",
"XX|XX|XX",
"XX|M1|XX",
],
SELFDELETE: [
"XX|XX|XX",
"XX|DL|XX",
"XX|XX|XX",
],
FOAM: [
"XX|XX|XX",
"XX|DL%5|XX",
"M2%25|M1%25|M2%25",
],
BUBBLE: [
"XX|XX|XX",
"XX|DL%0.25 AND FX%1|M1%5",
"XX|M1%1|M1%2",
],
STICKY: [
"XX|ST|XX",
"ST|XX|ST",
"XX|ST AND M1|XX",
],
MOLTEN: [
"XX|CR:fire%2.5|XX",
"M2|XX|M2",
"M1|M1|M1",
],
RADPOWDER: [
"XX|CR:radiation%1|XX",
"CR:radiation%1|XX|CR:radiation%1",
"M2|M1|M2",
],
RADMOLTEN: [
"XX|CR:fire,fire,fire,radiation%4.5|XX",
"M2 AND CR:radiation%1|XX|M2 AND CR:radiation%1",
"M1|M1|M1",
],
RADLIQUID: [
"XX|CR:radiation%2|XX",
"M2 AND CR:radiation%2|XX|M2 AND CR:radiation%2",
"M1|M1|M1",
],
BOUNCY: function(pixel) {
if (pixel.bx===undefined) {
// choose 1, 0, or -1
pixel.bx = Math.random() < 0.5 ? 1 : Math.random() < 0.5 ? 0 : -1;
pixel.by = Math.random() < 0.5 ? 1 : Math.random() < 0.5 ? 0 : -1;
// if both are 0, make one of them 1 or -1
if (pixel.bx===0 && pixel.by===0) {
if (Math.random() < 0.5) { pixel.bx = Math.random() < 0.5 ? 1 : -1; }
else { pixel.by = Math.random() < 0.5 ? 1 : -1; }
}
}
// move and invert direction if hit
if (!pixel.del && pixel.bx && !tryMove(pixel, pixel.x+pixel.bx, pixel.y)) { pixel.bx = -pixel.bx; }
if (!pixel.del && pixel.by && !tryMove(pixel, pixel.x, pixel.y+pixel.by)) { pixel.by = -pixel.by; }
},
FEEDPIXEL: function(pixel) {
if (!pixel.food) { pixel.food = 1 }
else { pixel.food ++ }
if (pixel.food > (elements[pixel.element].foodNeed||30)) {
// loop through adjacentCoords and check each pixel to lay an egg
for (var i = 0; i < adjacentCoords.length; i++) {
var x = pixel.x+adjacentCoords[i][0];
var y = pixel.y+adjacentCoords[i][1];
if (isEmpty(x, y)) {
if (elements[pixel.element].egg) {
createPixel(elements[pixel.element].egg,x,y)
}
else {
createPixel("egg",x,y)
pixelMap[x][y].animal = elements[pixel.element].baby || pixel.element;
if (elements[pixel.element].eggColor) {
pixelMap[x][y].color = pixelColorPick(pixelMap[x][y],elements[pixel.element].eggColor)
}
}
pixel.food = 0;
break;
}
}
}
},
KILLPIXEL1: function(pixel) {
pixel.dead = true;
},
KILLPIXEL2: function(pixel1,pixel2) {
pixel2.dead = true;
},
FLY: function(pixel, onHit) {
var nx = pixel.flipX ? -1 : 1;
var ny = Math.random() < 0.5 ? -1 : 1;
var hit = false;
if (!tryMove(pixel, pixel.x+nx, pixel.y+ny)) {
if (!tryMove(pixel, pixel.x+nx, pixel.y-ny)) {
if (!tryMove(pixel, pixel.x, pixel.y+ny)) {
if (!tryMove(pixel, pixel.x, pixel.y-ny)) {hit=[pixel.x, pixel.y-ny]}
}else {hit=[pixel.x, pixel.y+ny]}
}else {hit=[pixel.x+nx, pixel.y-ny]}
}else {hit=[pixel.x+nx, pixel.y+ny]}
if (hit && onHit) {
if (!isEmpty(hit[0], hit[1], true)) {
onHit(pixel, pixelMap[hit[0]][hit[1]]);
}
else {onHit(pixel);}
}
if (pixel.del) {return}
if (!isEmpty(pixel.x+nx,pixel.y) || Math.random() < 0.02) {
pixel.flipX = !pixel.flipX;
}
if (pixel.charge && elements[pixel.element].behaviorOn) {
pixelTick(pixel)
}
doDefaults(pixel);
},
CRAWLER: function(pixel) {
if (Math.random() < 0.08) { // flip
pixel.flipX = !pixel.flipX;
}
var dir = pixel.flipX ? -1 : 1;
var dirY = pixel.flipY ? -1 : 1;
if (!tryMove(pixel,pixel.x,pixel.y+dirY)) { // fall or climb
if (!tryMove(pixel,pixel.x+dir,pixel.y)) { // hits wall
if (!pixel.hilled && !isEmpty(pixel.x+dir,pixel.y,true) && pixelMap[pixel.x+dir][pixel.y].element === "ant_wall") {
pixel.hilled = true;
}
tryMove(pixel,pixel.x+dir,pixel.y + (Math.random() < 0.25 ? 1 : -1));
}
if (Math.random() < 0.01 && !isEmpty(pixel.x+dir,pixel.y+1,true) && eLists.CRAWLTHRU.indexOf(pixelMap[pixel.x+dir][pixel.y+1].element) !== -1) {
if (!pixel.hilled || !isEmpty(pixel.x+dir,pixel.y,true) && pixelMap[pixel.x+dir][pixel.y].element === "ant_wall") {
var wallCoords = [
[-1,-1],[1,-1],
[-1,0],[1,0],
[0,1]
];
if (!isEmpty(pixel.x,pixel.y-2)) {
wallCoords.push([0,-1])
}
if (Math.random() < 0.15) { wallCoords.push([-1,1]) }
if (Math.random() < 0.15) { wallCoords.push([1,1]) }
// loop through wallCoords, change pixel to ant_wall if in crawlthru
for (var i = 0; i < wallCoords.length; i++) {
var x = pixel.x+dir+wallCoords[i][0];
var y = pixel.y+1+wallCoords[i][1];
if (!isEmpty(x,y,true) && eLists.CRAWLTHRU.indexOf(pixelMap[x][y].element) !== -1) {
changePixel(pixelMap[x][y],"ant_wall");
}
}
deletePixel(pixel.x+dir,pixel.y+1);
tryMove(pixel,pixel.x+dir,pixel.y+1);
}
}
else if (Math.random() < 0.08 && !isEmpty(pixel.x+dir,pixel.y-1,true) && eLists.CRAWLTHRU.indexOf(pixelMap[pixel.x+dir][pixel.y-1].element) !== -1) {
swapPixels(pixel,pixelMap[pixel.x+dir][pixel.y-1]);
}
}
doDefaults(pixel);
}
}
textures = {
BRICK: [
"rrrrrwrrrrr",
"rrrrrwrrrrr",
"wwwwwwwwwww",
"rrwrrrrrwrr",
"rrwrrrrrwrr",
"wwwwwwwwwww",
"rrrrrrwrrrr",
"rrrrrrwrrrr",
"wwwwwwwwwww",
"rrrrwrrrrwr",
"rrrrwrrrrwr",
"wwwwwwwwwww"],
GLASS: [ // solid with streaks
"gggggggggggg",
"gggSgggggggg",
"ggSgggggggsg",
"gSgggggggsgg",
"ggggggggsggg",
"gggggggggggg",
"gggggggggggg",
"ggggsggggggg",
"gggsgggggggg",
"ggggggggggSg",
"gggggggggSgg",
"gggggggggggg",
],
}
eLists = {
ANIMAL: ["flea","ant","fly","firefly","bee","frog","fish","worm","termite","rat","slug","snail","stink_bug"],
CLEANANIMAL: ["ant","firefly","bee","frog","fish","tadpole"],
SEEDS: ["grass_seed","wheat_seed","flower_seed","bamboo_plant","mushroom_spore","corn_seed","potato_seed","cactus","pumpkin_seed"],
SOIL: ["dirt","mud","sand","wet_sand","clay_soil","clay","mycelium"],
CRAWLTHRU: ["dirt","sand","clay_soil","gravel","mulch","color_sand","grass"],
HIVEPLACE: ["wood","tree_branch","evergreen"]
}
function eListAdd(listName, itemList) {
if (!eLists[listName]) { eLists[listName] = []; }
if (!itemList) { return }
if (typeof itemList === "string") { itemList = [itemList]; }
for (var i = 0; i < itemList.length; i++) {
if (eLists[listName].indexOf(itemList[i]) === -1) {
eLists[listName].push(itemList[i]);
}
}
}
airDensity = settings.airdensity || 1.225; // kg/m^3
airTemp = settings.airtemp || 20; // Celsius
absoluteZero = settings.abszero || -273.15; // Celsius
// Element Properties
// name - display name of the element [optional]
// color - color of the element's pixel
// behavior - behavior of the element
// ignore - elements to ignore in behavior [must be an array]
// category - category in which the element will show up in
// density - density of the element [only used for movable elements] (kg/m^3)
// state - solid, liquid, or gas [only used for movable elements]
// reactions - instructions for when elements attempt to move onto each other (object)
// conduct - conductivity of the element (0-1)
// behaviorOn - behavior to override when powered
// colorOn - color to change to when powered
// temp - default temperature of the element (Celsius)
// tempHigh - highest temperature before state change (Celsius)
// tempLow - lowest temperature before state change (Celsius)
// stateHigh - element transformed into when tempHigh is reached
// stateLow - element transformed into when tempLow is reached
// viscosity - how slow a liquid will move (higher = slower) (cps)
// burn - chance of burning per tick (0-100) (%)
// burnTime - time to burn (ticks)
// burnInto - element to turn into after burning
// fireColor - color of the flame given off when burning
// burning - whether the element is burning on creation
// charge - charge of the element on creation
// hardness - chance of resisting damage (0-1)
elements = {
"heat": {
color: "#ff0000",
behavior: [
"HT:2|HT:2|HT:2",
"HT:2|HT:2|HT:2",
"HT:2|HT:2|HT:2",
],
tool: function(pixel) {
if (shiftDown) {pixel.temp += elements.heat.temp+(Math.random()*elements.heat.temp*1.5)*20;}
else {pixel.temp += elements.heat.temp+(Math.random()*elements.heat.temp*1.5);}
pixelTempCheck(pixel);
},
temp: 2,
category: "tools",
insulate:true,
canPlace: false,
desc: "Use on pixels to increase temperature."
},
"cool": {
color: "#0000ff",
behavior: [
"CO:2|CO:2|CO:2",
"CO:2|CO:2|CO:2",
"CO:2|CO:2|CO:2",
],
tool: function(pixel) {
if (shiftDown) {pixel.temp += elements.cool.temp+(Math.random()*elements.cool.temp*1.5)*20;}
else {pixel.temp += elements.cool.temp+(Math.random()*elements.cool.temp*1.5);}
pixelTempCheck(pixel);
},
temp: -2,
category: "tools",
insulate:true,
canPlace: false,
desc: "Use on pixels to decrease temperature."
},
"erase": { //hard-coded
color: "#fdb5ff",
behavior: [
"DL|DL|DL",
"DL|DL|DL",
"DL|DL|DL",
],
category: "tools",
canPlace: false,
desc: "Use on pixels to delete them."
},
"drag": {
color: "#c1cfb6",
behavior: [
"XX|XX|XX",
"XX|XX|SW",
"XX|XX|XX",
],
tool: function(pixel) {
if (!dragStart) {
dragStart = pixelTicks;
draggingPixels = [];
}
if (pixelTicks === dragStart && !pixel.drag && (elements[pixel.element].movable || shiftDown)) {
pixel.drag = true;
draggingPixels.push(pixel);
}
},
onMouseUp: function() {
if (!draggingPixels) { return; }
for (var i = 0; i < draggingPixels.length; i++) {
delete draggingPixels[i].drag;
}
dragStart = 0;
draggingPixels = null;
},
onUnselect: function() {
elements.drag.onMouseUp();
},
perTick: function() {
if (!draggingPixels) { return; }
for (var j = 0; j < (shiftDown ? 3 : 1); j++) {
for (var i = 0; i < draggingPixels.length; i++) {
var pixel = draggingPixels[i];
if (pixel.del) { continue }
const x = pixel.x;
const y = pixel.y;
const [mX, mY] = [mousePos.x, mousePos.y];
const empty = checkForEmptyPixels(x, y);
let bestVal = Math.sqrt(Math.pow(mX - x, 2) + Math.pow(mY - y, 2));
let best = null;
for (const pixelPair of empty) {
const x_ = x + pixelPair[0];
const y_ = y + pixelPair[1];
const c = Math.sqrt(Math.pow(mX - x_, 2) + Math.pow(mY - y_, 2));
if (c < bestVal) {
bestVal = c;
best = pixelPair;
}
}
if (best) {
tryMove(pixel, x + best[0], y + best[1], undefined, true);
}
}
}
},
rotatable: true,
category: "tools",
canPlace: false,
darkText: true,
desc: "Use on pixels to move them around."
},
"pick": { //hard-coded
color: ["#fa9b9b","#fae99b","#9bfab7","#9b9dfa"],
behavior: [
"CF|CF|CF",
"CF|DL%5|CF",
"CF|CF|CF",
],
category: "tools",
maxSize: 0,
darkText: true,
canPlace: false,
desc: "Use on a pixel to select its element."
},
"mix": { //hard-coded
color: ["#fff4b5","#a6a6a6"],
behavior: [
"SW|SW|SW",
"SW|DL%5|SW",
"SW|SW|SW",
],
category: "tools",
darkText: true,
canPlace: false,
desc: "Use on pixels to randomize their position."
},
"lookup": {
color: ["#5e807d","#5e807d","#679e99","#5e807d","#5e807d"],
behavior: behaviors.WALL,
tool: function(pixel) {
showInfo(pixel.element);
},
category: "tools",
maxSize: 0,
canPlace: false,
desc: "Use on a pixel to bring up its info screen."
},
"shock": { //hard-coded
color: "#ffff00",
behavior: [
"SH|SH|SH",
"SH|DL%5|SH",
"SH|SH|SH",
],
category: "tools",
darkText: true,
canPlace: false,
desc: "Use on pixels to increase electric charge."
},
"paint": {
color: ["#c27070","#c29c70","#c2c270","#70c270","#70c2c2","#7070c2","#c270c2"],
tool: function(pixel) {
if (!shiftDown) {
pixel.color = pixelColorPick(pixel,currentColor)
}
else {
// convert the hex of currentColor to rgb and set it as a string
var rgb = currentColor.replace("#","").match(/.{1,2}/g);
for (var i = 0; i < rgb.length; i++) {
rgb[i] = parseInt(rgb[i],16);
}
pixel.color = "rgb(" + rgb.join(",") + ")"
}
delete pixel.origColor;
},
customColor: true,
category: "tools",
canPlace: false,
desc: "Use on pixels to change color."
},
"sand": {
color: "#e6d577",
behavior: behaviors.POWDER,
tempHigh: 1700,
stateHigh: "molten_glass",
category: "land",
state: "solid",
density: 1602
},
"water": {
color: "#2167ff",
behavior: behaviors.LIQUID,
tempHigh: 100,
stateHigh: "steam",
tempLow: 0,
stateLow: "ice",
category: "liquids",
heatCapacity: 4.184,
reactions: {
"dirt": { // React with (water reacts with dirt to make mud)
elem1: null, // First element transforms into; in this case, water deletes itself
elem2: "mud", // Second element transforms into; in this case, dirt turns to mud
},
"sand": { elem1: null, elem2: "wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
"salt": { elem1: "salt_water", elem2: null, temp1:-20 },
"sugar": { elem1: "sugar_water", elem2: null },
"honey": { elem1: "sugar_water" },
"caramel": { elem1: "sugar_water" },
"molasses": { elem1: "sugar_water" },
"dust": { elem1: "dirty_water", elem2: null },
"ash": { elem1: "dirty_water", elem2: null },
"cyanide": { elem1: "dirty_water", elem2: null },
"cyanide_gas": { elem1: "dirty_water", elem2: null },
"carbon_dioxide": { elem1: "seltzer", elem2: null, oneway:true },
"sulfur": { elem1: "dirty_water", elem2: null },
"rat": { elem1: "dirty_water", chance:0.005 },
"plague": { elem1: "dirty_water", elem2: null },
"rust": { elem1: "dirty_water", chance:0.005 },
"lead": { elem1: "dirty_water", chance:0.005 },
"solder": { elem1: "dirty_water", chance:0.005 },
"fallout": { elem1: "dirty_water", chance:0.25 },
"radiation": { elem1: "dirty_water", chance:0.25 },
"uranium": { elem1: "dirty_water", chance:0.25 },
"rotten_meat": { elem1: "dirty_water", chance:0.25 },
"rotten_cheese": { elem1: "dirty_water", chance:0.25 },
"cancer": { elem1: "dirty_water", chance:0.25 },
"oil": { elem1: "dirty_water", chance:0.005 },
"dioxin": { elem1: "dirty_water", chance:0.1 },
"quicklime": { elem1: "slaked_lime", elem2: "slaked_lime", temp2:100, temp1:100, chance:0.05 },
"rock": { elem2: "wet_sand", chance: 0.00035 },
"limestone": { elem2: "wet_sand", chance: 0.00035 },
"tuff": { elem2: "wet_sand", color2:"#7a6b5c", chance: 0.00035 },
"ruins": { elem2: "rock", chance: 0.00035 },
"mudstone": { elem2: "mud", chance: 0.00035 },
"methane": { elem1:"primordial_soup", elem2:"primordial_soup", tempMin:60, charged:true },
"ammonia": { elem1:"primordial_soup", elem2:"primordial_soup", tempMin:60, charged:true },
"fly": { elem2:"dead_bug", chance:0.1, oneway:true },
"firefly": { elem2:"dead_bug", chance:0.1, oneway:true },
"bee": { elem2:"dead_bug", chance:0.05, oneway:true },
"stink_bug": { elem2:"dead_bug", chance:0.1, oneway:true },
"cured_meat": { elem1:"salt_water", elem2:"meat" },
// electrolysis:
"aluminum": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.0025 },
"zinc": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.015 },
"steel": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.0125 },
"iron": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.0125 },
"tin": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.01 },
"brass": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.001 },
"bronze": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.001 },
"copper": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.0075 },
"silver": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.0075 },
"gold": { elem1:["hydrogen","hydrogen","oxygen"], charged:true, chance:0.0075 },
},
state: "liquid",
density: 997,
conduct: 0.02,
stain: -0.5,
extinguish: true
},
"salt_water": {
color: "#4d85ff",
behavior: behaviors.LIQUID,
tempHigh: 102,
stateHigh: ["steam","salt"],
tempLow: -2,
stateLowName: "salt_ice",
category: "liquids",
reactions: {
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
"dust": { elem1: "dirty_water", elem2: null },
"ash": { elem1: "dirty_water", elem2: null },
"carbon_dioxide": { elem1: "dirty_water", elem2: null },
"sulfur": { elem1: "dirty_water", elem2: null },
"rat": { elem1: "dirty_water", chance:0.005 },
"plague": { elem1: "dirty_water", elem2: null },
"fallout": { elem1: "dirty_water", chance:0.25 },
"radiation": { elem1: "dirty_water", chance:0.25 },
"rust": { elem1: "dirty_water", chance:0.005 },
"lead": { elem1: "dirty_water", chance:0.005 },
"solder": { elem1: "dirty_water", chance:0.005 },
"quicklime": { elem1: null, elem2: "slaked_lime" },
"rock": { elem2: "wet_sand", chance: 0.0005 },
"limestone": { elem2: "wet_sand", chance: 0.0005 },
"fly": { elem2:"dead_bug", chance:0.1, oneway:true },
"firefly": { elem2:"dead_bug", chance:0.1, oneway:true },
"bee": { elem2:"dead_bug", chance:0.05, oneway:true },
"stink_bug": { elem2:"dead_bug", chance:0.1, oneway:true },
"cancer": { elem1: "dirty_water", chance:0.25 },
"oil": { elem1: "dirty_water", chance:0.005 },
"uranium": { elem1: "dirty_water", chance:0.25 },
// electrolysis:
"aluminum": { elem1:["hydrogen","hydrogen","oxygen","chlorine"], charged:true, chance:0.0025 },
"zinc": { elem1:["hydrogen","hydrogen","oxygen","chlorine"], charged:true, chance:0.015 },
"steel": { elem1:["hydrogen","hydrogen","oxygen","chlorine"], charged:true, chance:0.0125 },
"iron": { elem1:["hydrogen","hydrogen","oxygen","chlorine"], charged:true, chance:0.0125 },
"tin": { elem1:["hydrogen","hydrogen","oxygen","chlorine"], charged:true, chance:0.01 },
"brass": { elem1:["hydrogen","hydrogen","oxygen","chlorine"], charged:true, chance:0.001 },
"bronze": { elem1:["hydrogen","hydrogen","oxygen","chlorine"], charged:true, chance:0.001 },
"copper": { elem1:["hydrogen","hydrogen","oxygen","chlorine"], charged:true, chance:0.0075 },
"silver": { elem1:["hydrogen","hydrogen","oxygen","chlorine"], charged:true, chance:0.0075 },
"gold": { elem1:["hydrogen","hydrogen","oxygen","chlorine"], charged:true, chance:0.0075 },
},
state: "liquid",
density: 1026,
conduct: 0.1,
stain: -0.66,
extinguish: true
},
"sugar_water": {
color: "#8eaae6",
behavior: behaviors.LIQUID,
tempHigh: 105,
stateHigh: ["steam","sugar"],
tempLow: -5,
stateLowName: "sugar_ice",
category: "liquids",
reactions: {
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
"dust": { elem1: "dirty_water", elem2: null },
"ash": { elem1: "dirty_water", elem2: null },
"carbon_dioxide": { elem1: "soda", elem2: null },
"sulfur": { elem1: "dirty_water", elem2: null },
"charcoal": { elem1: "dirty_water", chance:0.005 },
"rat": { elem1: "dirty_water", chance:0.005 },
"plague": { elem1: "dirty_water", elem2: null },
"fallout": { elem1: "dirty_water", chance:0.25 },
"radiation": { elem1: "dirty_water", chance:0.25 },
"rust": { elem1: "dirty_water", chance:0.005 },
"lead": { elem1: "dirty_water", chance:0.005 },
"solder": { elem1: "dirty_water", chance:0.005 },
"rock": { elem2: "wet_sand", chance: 0.0004 },
"limestone": { elem2: "wet_sand", chance: 0.0004 },
"fly": { elem2:"dead_bug", chance:0.1, oneway:true },
"firefly": { elem2:"dead_bug", chance:0.1, oneway:true },
"bee": { elem2:"dead_bug", chance:0.05, oneway:true },
"stink_bug": { elem2:"dead_bug", chance:0.1, oneway:true },
"uranium": { elem1: "dirty_water", chance:0.25 },
// electrolysis:
"aluminum": { elem1:["hydrogen","hydrogen","oxygen","sugar"], charged:true, chance:0.0025 },
"zinc": { elem1:["hydrogen","hydrogen","oxygen","sugar"], charged:true, chance:0.015 },
"steel": { elem1:["hydrogen","hydrogen","oxygen","sugar"], charged:true, chance:0.0125 },
"iron": { elem1:["hydrogen","hydrogen","oxygen","sugar"], charged:true, chance:0.0125 },
"tin": { elem1:["hydrogen","hydrogen","oxygen","sugar"], charged:true, chance:0.01 },
"brass": { elem1:["hydrogen","hydrogen","oxygen","sugar"], charged:true, chance:0.001 },
"bronze": { elem1:["hydrogen","hydrogen","oxygen","sugar"], charged:true, chance:0.001 },
"copper": { elem1:["hydrogen","hydrogen","oxygen","sugar"], charged:true, chance:0.0075 },
"silver": { elem1:["hydrogen","hydrogen","oxygen","sugar"], charged:true, chance:0.0075 },
"gold": { elem1:["hydrogen","hydrogen","oxygen","sugar"], charged:true, chance:0.0075 },
},
hidden: true,
state: "liquid",
density: 1026,
conduct: 0.05,
stain: -0.45,
extinguish: true
},
"seltzer": {
color: ["#8eaae6","#82a4ed","#b5c5e8","#8eaae6","#82a4ed"],
behavior: [
"XX|CR:foam%3|XX",
"M2|XX|M2",
"M2|M1|M2",
],
tempHigh: 98,
stateHigh: ["steam","carbon_dioxide"],
tempLow: 0,
stateLowName: "seltzer_ice",
category: "liquids",
reactions: {
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
"rock": { elem2: "wet_sand", chance: 0.0004 },
"limestone": { elem2: null, chance: 0.0004 },
"sugar": { elem1: "soda", elem2: "foam" },
"sugar_water": { elem1: "soda", elem2: "foam" },
"fly": { elem2:"dead_bug", chance:0.1, oneway:true },
"firefly": { elem2:"dead_bug", chance:0.1, oneway:true },
"bee": { elem2:"dead_bug", chance:0.05, oneway:true },
"stink_bug": { elem2:"dead_bug", chance:0.1, oneway:true },
"plant": { elem1:"water" },
"evergreen": { elem1:"water" },
"cactus": { elem1:"water" },
"algae": { elem1:"water" },
"uranium": { elem1: "dirty_water", chance:0.25 },
// electrolysis:
"aluminum": { elem1:["hydrogen","hydrogen","oxygen","carbon_dioxide"], charged:true, chance:0.0025 },
"zinc": { elem1:["hydrogen","hydrogen","oxygen","carbon_dioxide"], charged:true, chance:0.015 },
"steel": { elem1:["hydrogen","hydrogen","oxygen","carbon_dioxide"], charged:true, chance:0.0125 },
"iron": { elem1:["hydrogen","hydrogen","oxygen","carbon_dioxide"], charged:true, chance:0.0125 },
"tin": { elem1:["hydrogen","hydrogen","oxygen","carbon_dioxide"], charged:true, chance:0.01 },
"lead": { elem1:["hydrogen","hydrogen","oxygen","carbon_dioxide"], charged:true, chance:0.01 },
"brass": { elem1:["hydrogen","hydrogen","oxygen","carbon_dioxide"], charged:true, chance:0.001 },
"bronze": { elem1:["hydrogen","hydrogen","oxygen","carbon_dioxide"], charged:true, chance:0.001 },
"copper": { elem1:["hydrogen","hydrogen","oxygen","carbon_dioxide"], charged:true, chance:0.0075 },
"silver": { elem1:["hydrogen","hydrogen","oxygen","carbon_dioxide"], charged:true, chance:0.0075 },
"gold": { elem1:["hydrogen","hydrogen","oxygen","carbon_dioxide"], charged:true, chance:0.0075 },
},
hidden: true,
state: "liquid",
density: 1026.91,
conduct: 0.05,
stain: -0.45,
extinguish: true
},
"dirty_water": {
color: ["#0e824e","#07755a","#0c6934"],
behavior: behaviors.LIQUID,
tempHigh: 105,
stateHigh: ["steam","carbon_dioxide"],
tempLow: -5,
stateLowName: "dirty_ice",
viscosity: 10,
category: "liquids",
reactions: {
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
"rock": { elem2: "wet_sand", chance: 0.0004 },
"limestone": { elem2: "wet_sand", chance: 0.0004 },
"plant": { elem1:"water", chance:0.05 },
"algae": { elem1:"water", chance:0.05 },
"charcoal": { elem1:"water", chance:0.02 },
"gravel": { elem1:"water", chance:0.01 },
"fly": { elem2:"dead_bug", chance:0.1, oneway:true },
"firefly": { elem2:"dead_bug", chance:0.1, oneway:true },
"bee": { elem2:"dead_bug", chance:0.05, oneway:true },
"stink_bug": { elem2:"dead_bug", chance:0.1, oneway:true }
},
hidden: true,
state: "liquid",
density: 1005,
conduct: 0.1,
extinguish: true
},
"pool_water": {
color: "#a8d2e3",
behavior: behaviors.LIQUID,
tempHigh: 105,
stateHigh: ["steam","chlorine"],
tempLow: -5,
stateLowName: "pool_ice",
category: "liquids",
reactions: {
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
"rock": { elem2: "wet_sand", chance: 0.001 },
"limestone": { elem2: "wet_sand", chance: 0.001 },
"plant": { elem2:"dead_plant", chance:0.05 },
"evergreen": { elem2:"dead_plant", chance:0.05 },
"cactus": { elem2:"dead_plant", chance:0.05 },
"grass": { elem2:"dead_plant", chance:0.05 },
"algae": { elem2:null, chance:0.05 },
"cell": { elem2:null, chance:0.05 },
"cancer": { elem2:null, chance:0.05 },
"plague": { elem2:null },
"flea": { elem2:"dead_bug", chance:0.05 },
"termite": { elem2:"dead_bug", chance:0.05 },
"ant": { elem2:"dead_bug", chance:0.05 },
"worm": { elem2:"dead_bug", chance:0.05 },
"fly": { elem2:"dead_bug", chance:0.05 },
"firefly": { elem2:"dead_bug", chance:0.05 },
"bee": { elem2:"dead_bug", chance:0.05 },
"stink_bug": { elem2:"dead_bug", chance:0.05 },
"dirty_water": { elem2:"water", chance:0.05 },
"slug": { elem2:null, chance:0.05 },
"snail": { elem2:null, chance:0.05 },
"lichen": { elem2:null, chance:0.05 },
"dead_bug": { elem2:null, chance:0.001 },
"pollen": { elem2:null },
"root": { elem2:"fiber", chance:0.05 },
"flower_seed": { elem2:"dead_plant", chance:0.05 },
"wheat_seed": { elem2:"dead_plant", chance:0.05 },
"bamboo_plant": { elem2:"dead_plant", chance:0.05 },
"potato_seed": { elem2:"dead_plant", chance:0.05 },
"corn_seed": { elem2:"dead_plant", chance:0.05 },
"sapling": { elem2:"dead_plant", chance:0.05 },
"pinecone": { elem2:"dead_plant", chance:0.05 },
"blood": { elem2:null, chance:0.01 },
"infection": { elem2:null, chance:0.05 },
"antibody": { elem2:null, chance:0.01 },
"poison": { elem2:null, chance:0.01 },
"charcoal": { elem1:"water", chance:0.02 },
},
hidden: true,
state: "liquid",
density: 992.72,
conduct: 0.15,
stain: -0.5,
extinguish: true
},
"dirt": {
color: ["#76552b","#5c4221","#573c1a","#6b481e"],
behavior: behaviors.POWDER,
tempHigh:1200,
tempLow: -50,
stateLow: "permafrost",
category:"land",
state: "solid",
density: 1220
},
"mud": {
color: "#382417",
behavior: behaviors.STURDYPOWDER,
reactions: {
"dirt": { elem1:"dirt", elem2:"mud", chance:0.0005, oneway:true },
"sand": { elem1:"dirt", elem2:"wet_sand", chance:0.0005, oneway:true },
"sawdust": { elem1:"mulch", "elem2":null },
"evergreen": { elem1:"mulch", "elem2":null },
},
tempHigh: 100,
stateHigh: "mudstone",
tempLow: -50,
stateLow: "permafrost",
category: "land",
state: "solid",
density: 1730,
stain: 0.02
},
"wet_sand": {
color: ["#a19348","#b5a85e"],
behavior: behaviors.STURDYPOWDER,
reactions: {
"sand": { elem1:"sand", elem2:"wet_sand", chance:0.0005, oneway:true },
"dirt": { elem1:"sand", elem2:"mud", chance:0.0005, oneway:true },
"gravel": { elem1:"cement", elem2:null, chance:0.2 },
},
tempHigh: 100,
stateHigh: "packed_sand",
tempLow: -50,
stateLow: "packed_sand",
category: "land",
state: "solid",
density: 1905
},
"rock": {
color: ["#808080","#4f4f4f","#949494"],
behavior: behaviors.POWDER,
reactions: {
"fly": { elem2:"dead_bug", chance:0.25, oneway:true },
"firefly": { elem2:"dead_bug", chance:0.2, oneway:true },
"stink_bug": { elem2:"dead_bug", chance:0.15, oneway:true },
"bee": { elem2:"dead_bug", chance:0.1, oneway:true },
"bird": { elem2:"feather", chance:0.025, oneway:true },
"egg": { elem2:"yolk", oneway:true },
"bone": { elem2:"oil", tempMin:300, chance:0.005, oneway:true },
"dead_plant": { elem2:"charcoal", tempMin:200, chance:0.005, oneway:true },
"charcoal": { elem2:"diamond", tempMin:800, tempMax:900, chance:0.005, oneway:true },
"sand": { elem2:"packed_sand", tempMin:500, chance:0.005, oneway:true },
"wet_sand": { elem2:"packed_sand", chance:0.005, oneway:true },
},
tempHigh: 950,
stateHigh: "magma",
category: "land",
state: "solid",
density: 2550,
hardness: 0.5,
breakInto: ["sand","gravel"]
},
"rock_wall": {
color: ["#666666","#363636","#7a7a7a"],
behavior: behaviors.WALL,
tool: function(pixel) {
if (pixel.element === "sun") {
pixel.eclipse = true;
if (Math.random() < 0.1) {
changePixel(pixel,"rock_wall");
pixel.temp = 20;
pixel.color = pixelColorPick(pixel,"#301B16")
}
}
},
canPlace: true,
tempHigh: 950,
stateHigh: "magma",
category: "land",
state: "solid",
density: 2550,
hardness: 0.5,
breakInto: "rock"
},
"mudstone": {
color: "#4a341e",
behavior: behaviors.SUPPORT,
tempHigh:1200,
stateHigh: "molten_dirt",
tempLow: -50,
stateLow: "permafrost",
category: "land",
state: "solid",
density: 1250,
breakInto: "dirt"
},
"packed_sand": {
color: ["#a1975d","#b5ab70"],
behavior: behaviors.SUPPORT,
tempHigh:1700,
stateHigh: "molten_glass",
category: "land",
state: "solid",
density: 1682,
breakInto: "sand"
},
"plant": {
color: "#00bf00",
behavior: behaviors.WALL,
reactions: {
"vinegar": { elem1:"dead_plant", elem2:null, chance:0.035 },
"baking_soda": { elem1:"dead_plant", elem2:null, chance:0.01 },
"bleach": { elem1:"dead_plant", elem2:null, chance:0.05 },
"alcohol": { elem1:"dead_plant", elem2:null, chance:0.035 },
"mercury": { elem1:"dead_plant", elem2:null, chance:0.01 },
"stench": { elem2:null, chance:0.25 },
"chlorine": { stain1:"#a2bf00" },
},
category:"life",
tempHigh: 100,
stateHigh: "dead_plant",
tempLow: -1.66,
stateLow: "frozen_plant",
burn:15,
burnTime:60,
burnInto: "dead_plant",
breakInto: "dead_plant",
state: "solid",
density: 1050,
forceSaveColor: true
},
"dead_plant": {
color: ["#826521","#826021","#825321","#70360c"],
behavior: [
"XX|XX|XX",
"XX|XX|XX",
"M2|M1|M2",
],
category:"life",
tempHigh: 300,
stateHigh: "fire",
tempLow: -2,
stateLow: "frozen_plant",
burn:85,
burnTime:45,
state: "solid",
density: 1050,
hidden: true
},
"frozen_plant": {
color: "#00bf8c",
behavior: behaviors.WALL,
category:"life",
temp: -2.66,
tempHigh: 7,
stateHigh: "dead_plant",
state: "solid",
density: 1050,
hidden: true
},
"grass": {
color: ["#439809","#258b08","#118511","#127b12","#136d14"],
tick: function(pixel) {
if (!tryMove(pixel,pixel.x,pixel.y+1)) {
if (pixel.h < 2 && Math.random() < 0.0005 && isEmpty(pixel.x,pixel.y-1)) {
createPixel(pixel.element,pixel.x,pixel.y-1);
pixelMap[pixel.x][pixel.y-1].h = pixel.h+1;
}
var coords = [
[pixel.x+1,pixel.y],
[pixel.x-1,pixel.y],
[pixel.x+1,pixel.y+1],
[pixel.x-1,pixel.y+1],
];
for (var i = 0; i < coords.length; i++) {
if (Math.random() < 0.005 && isEmpty(coords[i][0],coords[i][1])) {
if (!isEmpty(coords[i][0],coords[i][1]+1,true)) {
var soil = pixelMap[coords[i][0]][coords[i][1]+1];
if (eLists.SOIL.indexOf(soil.element) !== -1) {
createPixel(pixel.element,coords[i][0],coords[i][1]);
}
}
}
}
}
doDefaults(pixel);
},
properties: {
"h": 0
},
reactions: {
"vinegar": { elem1:"dead_plant", elem2:null, chance:0.035 },
"mercury": { elem1:"dead_plant", elem2:null, chance:0.01 },
"alcohol": { elem1:"dead_plant", elem2:null, chance:0.035 },
},
tempHigh: 100,
stateHigh: "dead_plant",
tempLow: -2,
stateLow: "frozen_plant",
burn:3,
burnTime:20,
breakInto: "dead_plant",
category:"life",
state: "solid",
density: 1400,
seed: "grass_seed"
},
"algae": {
color: ["#395706","#6f9315","#9dca19"],
behavior: [
"XX|XX|XX",
"SW:water,salt_water,dirty_water,sugar_water%1|XX|SW:water,salt_water,dirty_water,sugar_water%1",
"M2%10|M1|M2%10",
],
tick: function(pixel) {
if (Math.random() < 0.01 && !isEmpty(pixel.x+1,pixel.y+1,true) && isEmpty(pixel.x+1,pixel.y)) {
var newPixel = pixelMap[pixel.x+1][pixel.y+1];
if (newPixel.element !== "algae" && elements[newPixel.element].state === "liquid") {
createPixel(pixel.element,pixel.x+1,pixel.y);
}
}
if (Math.random() < 0.01 && !isEmpty(pixel.x-1,pixel.y+1,true) && isEmpty(pixel.x-1,pixel.y)) {
var newPixel = pixelMap[pixel.x-1][pixel.y+1];
if (newPixel.element !== "algae" && elements[newPixel.element].state === "liquid") {
createPixel(pixel.element,pixel.x-1,pixel.y);
}
}
doDefaults(pixel);
},
reactions: {
"wood": { elem1:"lichen" },
"chlorine": { elem1:"dead_plant", elem2:null, chance:0.035 },
"liquid_chlorine": { elem1:"dead_plant", elem2:null, chance:0.035 },
"baking_soda": { elem1:"dead_plant", elem2:null, chance:0.035 },
"broth": { elem2:"water", chance:0.05 },
"tea": { elem2:"water", chance:0.05 },
},
category:"life",
tempHigh: 70,
stateHigh: "dead_plant",
tempLow: 0,
stateLow: "frozen_plant",
burn:95,
burnTime:20,
state: "liquid",
density: 920,
seed: "algae"
},
"concrete": {
color: "#ababab",
behavior: behaviors.SUPPORT,
tempHigh: 1500,
stateHigh: "magma",
category: "powders",
state: "solid",
density: 2400,
hardness: 0.5,
breakInto: "dust",
darkText: true
},
"wall": {
color: "#808080",
behavior: behaviors.WALL,
category: "solids",
insulate: true,
hardness: 1,
noMix: true
},
"fire": {
color: ["#ff6b21","#ffa600","#ff4000"],
tick: function(pixel){
behaviors.UL_UR_OPTIMIZED(pixel);
if (!pixel.del && settings.burn===0 && (pixelTicks-pixel.start > 70) && Math.random() < 0.1 ) { changePixel(pixel,"smoke") }
},
reactions: {
"water": { elem1: "smoke" },
"steam": { elem1: "smoke" },
"carbon_dioxide": { elem1: "smoke" },
"foam": { elem1: "smoke" },
"dirty_water": { elem1: "smoke" },
"salt_water": { elem1: "smoke" },
"sugar_water": { elem1: "smoke" },
"seltzer": { elem1: "smoke" },
"pool_water": { elem1: "smoke" },
"oxygen": { elem2: null, chance:0.1 },
},
temp:600,
tempLow:100,
stateLow: "smoke",
tempHigh: 7000,
stateHigh: "plasma",
category: "energy",
burning: true,
burnTime: 25,
burnInto: "smoke",
state: "gas",
density: 0.1,
ignoreAir: true,
noMix: true
},
"bomb": {
color: "#524c41",
behavior: [
"XX|EX:10|XX",
"XX|XX|XX",
"M2|M1 AND EX:10|M2",
],
category: "weapons",
state: "solid",
density: 1300,
excludeRandom: true,
cooldown: defaultCooldown
},
"steam": {
color: "#abd6ff",
behavior: behaviors.GAS,
reactions: {
"steam": { elem1: null, elem2: "cloud", chance:0.3, "y":[0,15], "setting":"clouds" },
"rain_cloud": { elem1: "rain_cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"cloud": { elem1: "cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"snow_cloud": { elem1: "rain_cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"hail_cloud": { elem1: "rain_cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"thunder_cloud": { elem1: "rain_cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"pyrocumulus": { elem1: "cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"anesthesia": { elem1:"acid_cloud", elem2:null, chance:0.05, "y":[0,12], "setting":"clouds" },
"fire_cloud": { elem1: "cloud", elem2: "pyrocumulus", chance:0.4, "y":[0,12], "setting":"clouds" },
"smoke": { elem1: "smog", elem2: null, chance:0.001 },
"carbon_dioxide": { elem1: "smog", elem2: null, chance:0.001 },
"plasma": { elem1:"ozone", tempMin:500, charged:true },
"copper": { elem1:"oxygen", elem2:"oxidized_copper", chance:0.01 },
"bronze": { elem1:"oxygen", elem2:"oxidized_copper", chance:0.005 },
"iron": { elem1:"oxygen", elem2:"rust", chance:0.005 },
"steel": { elem1:"oxygen", elem2:"rust", chance:0.004 },
},
temp: 150,
tempLow: 95,
extraTempLow: {
0: "rime"
},
stateLow: "water",
category: "gases",
state: "gas",
density: 0.6,
conduct: 0.002,
stain: -0.05,
alias: "water vapor",
extinguish: true
},
"ice": {
color: "#b2daeb",
behavior: behaviors.WALL,
temp: -5,
tempHigh: 5,
stateHigh: "water",
category: "solids",
state: "solid",
density: 917,
breakInto: "snow"
},
"rime": {
color: "#e6f2f7",
behavior: behaviors.WALL,
behaviorOn: [
"XX|XX|XX",
"XX|CH:rain_cloud|XX",
"XX|XX|XX",
],
temp: -10,
tempHigh: 20,
stateHigh: "water",
category: "solids",
hidden: true,
state: "solid",
density: 250,
conduct: 1,
breakInto: "packed_snow"
},
"snow": {
color: "#e1f8fc",
behavior: behaviors.POWDER,
reactions: {
"water": { elem1:"slush", elem2:"slush" },
"salt_water": { elem1:"slush", elem2:"slush" },
"dirty_water": { elem1:"slush", elem2:"slush" },
"pool_water": { elem1:"slush", elem2:"slush" },
"sugar_water": { elem1:"slush", elem2:"slush" },
"seltzer": { elem1:"slush", elem2:"slush" },
"uranium": { elem1:"dirty_water", chance:0.001 },
},
temp: -5,
tempHigh: 18,
tempLow: -100,
stateLow: "packed_snow",
stateHigh: "water",
category: "land",
state: "solid",
density: 100
},
"slush": {
color: "#81bcd4",
behavior: behaviors.LIQUID,
reactions: {
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
"uranium": { elem1:"dirty_water", chance:0.25 },
},
temp: -5,
tempHigh: 18,
tempLow: -20,
stateLow: "ice",
stateHigh: "water",
category: "liquids",
state: "liquid",
density: 95,
viscosity: 100,
hidden: true
},
"packed_snow": {
color: "#bcdde3",
behavior: behaviors.SUPPORTPOWDER,
temp: 0,
tempHigh: 20,
tempLow: -200,
stateLow: "ice",
stateHigh: "water",
breakInto: "snow",
category: "land",
state: "solid",
density: 400,
hidden: true
},
"wood": {
color: "#a0522d",
behavior: behaviors.WALL,
tempHigh: 400,
stateHigh: ["ember","charcoal","fire","fire","fire"],
category: "solids",
burn: 5,
burnTime: 300,
burnInto: ["ember","charcoal","fire"],
state: "solid",
hardness: 0.15,
breakInto: "sawdust",
forceSaveColor: true
},
"smoke": {
color: "#383838",
behavior: behaviors.DGAS,
reactions: {
"steam": { elem1: "pyrocumulus", chance:0.08, "y":[0,12], "setting":"clouds" },
"rain_cloud": { elem1: "pyrocumulus", chance:0.08, "y":[0,12], "setting":"clouds" },
"cloud": { elem1: "pyrocumulus", chance:0.08, "y":[0,12], "setting":"clouds" },
"snow_cloud": { elem1: "pyrocumulus", chance:0.08, "y":[0,12], "setting":"clouds" },
"hail_cloud": { elem1: "pyrocumulus", chance:0.08, "y":[0,12], "setting":"clouds" },
"thunder_cloud": { elem1: "pyrocumulus", chance:0.08, "y":[0,12], "setting":"clouds" },
"acid_cloud": { elem1: "pyrocumulus", chance:0.05, "y":[0,12], "setting":"clouds" },
"fire_cloud": { elem1: "pyrocumulus", chance:0.05, "y":[0,12], "setting":"clouds" },
"rad_cloud": { elem1: "pyrocumulus", chance:0.05, "y":[0,12], "setting":"clouds" },
"pyrocumulus": { elem1: "pyrocumulus", chance:0.08, "y":[0,12], "setting":"clouds" }
},
temp: 114,
tempHigh: 605,
stateHigh: "fire",
category: "gases",
state: "gas",
density: 1180,
stain: 0.075,
noMix: true
},
"magma": {
color: ["#ff6f00","#ff8c00","#ff4d00"],
behavior: behaviors.MOLTEN,
reactions: {
"ice": { elem1: "basalt" },
"ash": { elem1: "molten_tuff", "elem2":null },
"molten_ash": { elem1: "molten_tuff", "elem2":null },
"charcoal": { elem2:"diamond", tempMin:800, tempMax:900, chance:0.005, oneway:true },
},
temp: 1200,
tempLow: 800,
stateLow: ["basalt","basalt","basalt","rock"],
viscosity: 10000,
category: "liquids",
state: "liquid",
density: 2725,
alias: "lava"
},
"plasma": {
color: ["#8800ff","#b184d9","#8800ff"],
behavior: behaviors.DGAS,
behaviorOn: [
"M2|M1|M2",
"CL%5 AND M1|XX|CL%5 AND M1",
"M2|M1|M2",
],
temp:7065,
tempLow:5000,
stateLow: "fire",
category: "energy",
state: "gas",
density: 1,
//charge: 0.5,
conduct: 1
},
"cold_fire": {
color: ["#21cbff","#006aff","#00ffff"],
behavior: [
"M1|M1|M1",
"M2|CH:smoke%8|M2",
"XX|M2|XX",
],
reactions: {
"fire": { elem1: "smoke", elem2: "smoke" },
"plasma": { elem1: "light", elem2: "light" }
},
temp:-200,
tempHigh:0,
stateHigh: "smoke",
category: "energy",
state: "gas",
density: 0.1,
ignoreAir: true
},
"glass": {
color: ["#5e807d","#5e807d","#679e99","#5e807d","#5e807d"],
colorPattern: textures.GLASS,
colorKey: {
"g": "#5e807d",
"s": "#638f8b",
"S": "#679e99"},
behavior: behaviors.WALL,
reactions: {
"radiation": { elem1:"rad_glass", chance:0.33 },
"rad_steam": { elem1:"rad_glass", elem2:null, chance:0.33 },
"fallout": { elem1:"rad_glass", elem2:"radiation", chance:0.1 }
},
tempHigh: 1500,
category: "solids",
state: "solid",
density: 2500,
breakInto: "glass_shard",
noMix: true
},
"molten_glass": {
reactions: {
"radiation": { elem1:"molten_rad_glass", chance:0.66 },
"rad_steam": { elem1:"molten_rad_glass", elem2:null, chance:0.33 },
"molten_uranium": { elem1:"molten_rad_glass", elem2:null },
"fallout": { elem1:"molten_rad_glass", elem2:"radiation" }
}
},
"molten_rad_glass": {
behavior: behaviors.RADMOLTEN,
},
"rad_glass": {
color: ["#648c64","#648c64","#6aad83","#648c64","#648c64"],
colorPattern: textures.GLASS,
colorKey: {
"g": "#648c64",
"s": "#679D74",
"S": "#6aad83"},
behavior: [
"XX|CR:radiation%0.075|XX",
"CR:radiation%0.075|XX|CR:radiation%0.075",
"XX|CR:radiation%0.075|XX",
],
tempHigh: 1500,
category: "solids",
state: "solid",
density: 2500,
breakInto: "rad_shard",
hidden: true,
noMix: true
},
"meat": {
color: ["#9e4839","#ba6449","#d2856c","#a14940"],
behavior: [
"XX|XX|XX",
"SP|XX|SP",
"XX|M1|XX",
],
reactions: {
"dirty_water": { elem1:"rotten_meat", chance:0.1 },
"fly": { elem1:"rotten_meat", chance:0.2 },
"dioxin": { elem1:"rotten_meat", elem2:null, chance:0.1 },
"uranium": { elem1:"rotten_meat", chance:0.1 },
"cancer": { elem1:"rotten_meat", chance:0.1 },
"plague": { elem1:"rotten_meat", elem2:null, chance:0.3 },
"ant": { elem1:"rotten_meat", chance:0.1 },
"worm": { elem1:"rotten_meat", chance:0.1 },
"rat": { elem1:"rotten_meat", chance:0.3 },
"mushroom_spore": { elem1:"rotten_meat", chance:0.1 },
"mushroom_stalk": { elem1:"rotten_meat", chance:0.1 },
"mercury": { elem1:"rotten_meat", elem2:null, chance:0.2 },
"mercury_gas": { elem1:"rotten_meat", elem2:null, chance:0.1 },
"virus": { elem1:"rotten_meat", chance:0.1 },
"poison": { elem1:"rotten_meat", elem2:null, chance:0.5 },
"infection": { elem1:"rotten_meat", elem2:null, chance:0.1 },
"ink": { elem1:"rotten_meat", elem2:null, chance:0.1 },
"acid": { elem1:"rotten_meat", elem2:null, chance:0.5 },
"acid_gas": { elem1:"rotten_meat", chance:0.4 },
"cyanide": { elem1:"rotten_meat", elem2:null, chance:0.5 },
"cyanide_gas": { elem1:"rotten_meat", elem2:null, chance:0.5 },
"rotten_cheese": { elem1:"rotten_meat", chance:0.02 },
"water": { elem2:"broth", tempMin:70 },
"salt_water": { elem2:"broth", tempMin:70 },
"sugar_water": { elem2:"broth", tempMin:70 },
"seltzer": { elem2:"broth", tempMin:70 },
"salt": { elem1:"cured_meat" },
},
tempHigh: 100,
stateHigh: "cooked_meat",
tempLow: -18,
stateLow: "frozen_meat",
category:"food",
burn:15,
burnTime:200,
burnInto:"cooked_meat",
state: "solid",
density: 1019.5,
conduct: 0.2,
isFood: true
},
"rotten_meat": {
color: ["#b8b165","#b89765"],
behavior: [
"XX|CR:plague,stench,stench,stench,fly%0.25 AND CH:meat>rotten_meat%1|XX",
"SP%99 AND CH:meat>rotten_meat%1|XX|SP%99 AND CH:meat>rotten_meat%1",
"XX|M1 AND CH:meat>rotten_meat%1|XX",
],
reactions: {
"water": { elem2:"broth", tempMin:70, color2:"#d7db69" },
"salt_water": { elem2:"broth", tempMin:70, color2:"#d7db69" },
"sugar_water": { elem2:"broth", tempMin:70, color2:"#d7db69" },
"dirty_water": { elem2:"broth", tempMin:70, color2:"#d7db69" },
"seltzer": { elem2:"broth", tempMin:70, color2:"#d7db69" }
},
tempHigh: 300,
stateHigh: ["plague","ash","ammonia"],
category:"food",
hidden: true,
burn:12,
burnTime:200,
burnInto:["plague","ash","ammonia"],
state: "solid",
density: 1005,
conduct: 0.1,
isFood: true
},
"cured_meat": {
color: ["#be5c4b","#c8846f","#dda592","#bc6157"],
behavior: [
"XX|XX|XX",
"SP|XX|SP",
"XX|M1|XX",
],
reactions: {
"water": { elem2:"broth", tempMin:70 },
"salt_water": { elem2:"broth", tempMin:70 },
"sugar_water": { elem2:"broth", tempMin:70 },
"seltzer": { elem2:"broth", tempMin:70 },
},
tempHigh: 100,
stateHigh: "cooked_meat",
category:"food",
burn:15,
burnTime:200,
burnInto:"cooked_meat",
state: "solid",
density: 1019.5,
conduct: 0.3,
isFood: true,
hidden: true
},
"cooked_meat": {
color: ["#ae7d5b","#9b6d54","#7e4d31"],
behavior: behaviors.STURDYPOWDER,
tick: function(pixel) {
if (pixel.temp > 100 && Math.random() < 0.0025 && isEmpty(pixel.x,pixel.y-1)) {
changePixel(pixel,"grease")
}
},
reactions: {
"water": { elem2:"broth", tempMin:70 },
"salt_water": { elem2:"broth", tempMin:70 },
"sugar_water": { elem2:"broth", tempMin:70 },
"dirty_water": { elem2:"broth", tempMin:70, color2:"#d7db69" },
"seltzer": { elem2:"broth", tempMin:70 }
},
tempHigh: 300,
stateHigh: "ash",
category:"food",
hidden:true,
burn:10,
burnTime:200,
burnInto: "ash",
state: "solid",
density: 1005,
isFood: true
},
"frozen_meat": {
color: ["#399e8f","#49baa9","#6cd2c6","#40a197"],
behavior: behaviors.STURDYPOWDER,
temp: -18,
tempHigh: 0,
stateHigh: "meat",
category:"food",
hidden:true,
state: "solid",
density: 1067.5,
isFood: true
},
"salt": {
color: ["#f2f2f2","#e0e0e0"],
behavior: behaviors.POWDER,
reactions: {
"ice": { elem1:null, elem2:"salt_water", chance:0.1 },
"rime": { elem1:null, elem2:"salt_water", chance:0.075 },
"snow": { elem1:null, elem2:"salt_water", chance:0.25 },
"packed_snow": { elem1:null, elem2:"salt_water", chance:0.05 },
"packed_ice": { elem1:null, elem2:"salt_water", chance:0.01 }
},
category: "food",
tempHigh: 801,
state: "solid",
density: 2160,
fireColor: "#F1E906",
alias: "sodium chloride"
},
"molten_salt": {
conduct: 0.1,
},
"sugar": {
color: "#f2f2f2",
behavior: behaviors.POWDER,
reactions: {
"grape": { elem1:null, elem2:"jelly", chance:0.005, tempMin:100 },
},
category: "food",
tempHigh: 186,
stateHigh: "caramel",
state: "solid",
density: 1590,
isFood: true
},
"flour": {
color: ["#f0e2b7","#f0e4c0","#ded1ab"],
behavior: behaviors.POWDER,
reactions: {
"water": { elem1: "dough", elem2: null },
"salt_water": { elem1: "dough", elem2: null },
"sugar_water": { elem1: "dough", elem2: null },
"seltzer": { elem1: "dough", elem2: null },
"pool_water": { elem1: "dough", elem2: null },
"juice": { elem1: "dough", elem2: null },
"vinegar": { elem1: "dough", elem2: null },
"yolk": { elem1: "batter", elem2: null },
"yogurt": { elem1: "batter", elem2: null },
"honey": { elem1:"gingerbread", elem2:null },
"molasses": { elem1:"gingerbread", elem2:null },
"sap": { elem1:"gingerbread", elem2:null },
"caramel": { elem1:"gingerbread", elem2:null },
"broth": { elem1:"dough", elem2:null },
"soda": { elem1:"dough", elem2:null },
"tea": { elem1:"dough", elem2:null },
"blood": { elem1:"dough", elem2:null },
"infection": { elem1:"dough", elem2:null },
"antibody": { elem1:"dough", elem2:null },
"milk": { elem1:"dough", elem2:null },
"cream": { elem1:"dough", elem2:null },
},
category: "food",
tempHigh: 400,
stateHigh: "fire",
burn:40,
burnTime:25,
state: "solid",
density: 600,
isFood: true
},
"wire": {
color: "#4d0a03",
behavior: behaviors.WALL,
category: "machines",
insulate: true,
conduct: 1,
noMix: true
},
"battery": {
color: "#9c6c25",
behavior: [
"XX|SH|XX", // shocks (adds charge)
"SH|XX|SH",
"XX|SH|XX",
],
category: "machines",
tempHigh: 1455.5,
stateHigh: ["molten_steel","explosion","acid_gas"]
},
"cloner": {
color: "#dddd00",
behavior: behaviors.CLONER,
ignore: ["ecloner","slow_cloner","clone_powder","floating_cloner","wall","ewall"],
category:"machines",
insulate:true,
hardness: 1,
darkText: true,
},
"sensor": {
color: "#bebfa3",
tick: function(pixel) {
for (var i = 0; i < adjacentCoords.length; i++) {
var coords = adjacentCoords[i];
var x = pixel.x + coords[0];
var y = pixel.y + coords[1];
if (!isEmpty(x,y,true)) {
var sensed = pixelMap[x][y];
if (sensed.con || elements[sensed.element].movable) {
pixel.charge = 5;
break;
}
}
}
doDefaults(pixel);
},
conduct: 1,
movable: false,
category:"machines",
darkText: true,
},
"heater": {
color: "#881111",
behavior: [
"XX|HT:2|XX",
"HT:2|XX|HT:2",
"XX|HT:2|XX",
],
category:"machines",
insulate:true
},
"cooler": {
color: "#111188",
behavior: [
"XX|CO:2|XX",
"CO:2|XX|CO:2",
"XX|CO:2|XX",
],
category:"machines",
insulate:true
},
"random": { //hard-coded
color: ["#3e5f8a","#a334ec","#ea96f9","#a6ecf6","#70ebc8","#d9286b","#7eed91","#a18b30"],
behavior: behaviors.WALL,
tick: function(pixel) {
changePixel(pixel,randomChoices[Math.floor(Math.random() * randomChoices.length)]);
},
category: "special",
excludeRandom: true
},
"image": {
color: ["#78bbff","#5bb81a"],
onSelect: function() {
// prompt to upload an image file, then store the image in placingImage
var file = document.createElement("input");
file.type = "file";
file.accept = "image/*";
file.onchange = function() {
setTimeout(function(){
var reader = new FileReader();
reader.onload = function(e) {
var img = new Image();
img.onload = function() {
placingImage = img;
}
img.src = e.target.result;
file.value = "";
}
reader.readAsDataURL(file.files[0]);
},500);
}
file.click();
},
onUnselect: function() {
placingImage = null;
},
tool: function() {},
category: "special",
},
"unpaint": {
color: ["#ffffff","#000000"],
tool: function(pixel) {
var r = elements.unpaint.reactions[pixel.element];
if (r && r.elem2) {
changePixel(pixel,r.elem2)
}
if (!elements[pixel.element].customColor) {
pixel.color = pixelColorPick(pixel)
}
},
reactions: {
"color_sand": { elem2:"sand" },
"stained_glass": { elem2:"glass" },
"molten_stained_glass": { elem2:"molten_glass" },
"rainbow": { elem2:"art" },
"static": { elem2:"art" },
"border": { elem2:"wall" },
"color_smoke": { elem2:"smoke" },
"spray_paint": { elem2:"smoke" },
"dye": { elem2:"ink" },
},
category: "special",
desc: "Use on pixels to return their original color."
},
"uncharge": {
color: "#0000ff",
tool: function(pixel) {
if (pixel.charge) {
delete pixel.charge;
pixel.chargeCD = 16;
}
var r = elements.uncharge.reactions[pixel.element];
if (r) {
if (r.elem2) { changePixel(pixel,r.elem2) }
else { deletePixel(pixel.x,pixel.y) }
}
},
reactions: {
"electric": { elem2:null },
"lightning": { elem2:null },
"proton": { elem2:"neutron" },
},
category: "special",
excludeRandom: true,
desc: "Use on pixels to remove electric charge."
},
"unburn": {
color: "#383645",
tool: function(pixel) {
if (pixel.burning) {
delete pixel.burning;
delete pixel.burnStart;
}
var r = elements.unburn.reactions[pixel.element];
if (r) {
if (r.elem2) { changePixel(pixel,r.elem2) }
else { deletePixel(pixel.x,pixel.y) }
}
},
reactions: {
"fire": { elem2:"smoke" },
"plasma": { elem2:"smoke" },
"ember": { elem2:"ash" },
"fw_ember": { elem2:"smoke" },
"torch": { elem2:"wood" },
},
category: "special",
excludeRandom: true,
desc: "Use on pixels to stop burning."
},
"smash": {
color: ["#666666","#888888","#666666"],
tool: function(pixel) {
if (elements[pixel.element].breakInto !== undefined) {
// times 0.25 if not shiftDown else 1
if (Math.random() < (elements[pixel.element].hardness || 1) * (shiftDown ? 1 : 0.25)) {
var breakInto = elements[pixel.element].breakInto;
// if breakInto is an array, pick one
if (Array.isArray(breakInto)) {
breakInto = breakInto[Math.floor(Math.random() * breakInto.length)];
}
if (breakInto === null) {
deletePixel(pixel.x,pixel.y);
return;
}
var oldelement = pixel.element;
changePixel(pixel,breakInto);
pixelTempCheck(pixel);
if (elements[oldelement].breakIntoColor) {
pixel.color = pixelColorPick(pixel, elements[oldelement].breakIntoColor);
}
}
}
},
category: "tools",
excludeRandom: true,
desc: "Use on pixels to break them, if possible."
},
"filler": {
color: "#ae4cd9",
behavior: behaviors.FILL,
category:"special",
excludeRandom: true,
reactions: {
"neutron": { elem1:"lattice" },
"proton": { elem1:"vertical" },
"electric": { elem1:"horizontal" },
"positron": { elem1:"vertical" },
"plasma": { elem1:"armageddon", tempMin:500, charged:true },
}
},
"lattice": {
color: "#cb4cd9",
behavior: [
"CL|XX|CL",
"XX|XX|XX",
"CL|XX|CL",
],
tick: function(pixel) {
for (var i = 0; i < adjacentCoords.length; i++) {
var coords = adjacentCoords[i];
var x = pixel.x + coords[0];
var y = pixel.y + coords[1];
if (!isEmpty(x,y,true) && pixelMap[x][y].element === "lattice") {
deletePixel(x,y)
}
}
},
hidden: true,
category:"special",
excludeRandom: true,
movable: false
},
"gravel": {
color: ["#e3e0df","#b1aba3","#74736d","#524b47"],
behavior: behaviors.POWDER,
reactions: {
"broth": { elem2:"water", chance:0.01 },
"tea": { elem2:"water", chance:0.01 },
},
category:"land",
tempHigh: 950,
stateHigh: "magma",
state: "solid",
density: 1680,
hardness: 0.2,
breakInto: "sand"
},
"slime": {
color: "#81cf63",
behavior: behaviors.LIQUID,
viscosity: 5000,
tempHigh: 120,
stateHigh: "steam",
tempLow: 0,
category:"liquids",
state: "liquid",
density: 1450,
stain: 0.05
},
"cement": {
color: "#b5b5b5",
behavior: behaviors.LIQUID,
tick: function(pixel) {
if (pixelTicks - pixel.start > 100 && Math.random() < 0.1) {
changePixel(pixel,"concrete")
}
},
onMix: function(pixel) {
pixel.start = pixelTicks;
},
category:"liquids",
tempHigh: 1550,
stateHigh: "magma",
tempLow: -10,
stateLow: "concrete",
state: "solid",
density: 1440,
hardness: 0.1,
viscosity: 1000,
darkText: true
},
"dust": {
color: "#666666",
behavior: behaviors.POWDER,
category: "powders",
burn: 10,
burnTime: 1,
tempHigh: 425,
stateHigh: "fire",
state: "solid",
density: 1490
},
"void": {
color: "#262626",
behavior: behaviors.DELETE,
category:"special",
hardness: 1,
excludeRandom: true
},
"sun": {
color: "#ffffbd",
tick: function(pixel) {
// minimum 1726
// maximum 7726
if (pixel.eclipse) { pixel.color = pixelColorPick(pixel,"#FD8C03"); var c=0.01}
else if (pixel.temp < 1500) { pixel.color = pixelColorPick(pixel,"#7a4e43"); var c=0 }
else if (pixel.temp < 3600) { pixel.color = pixelColorPick(pixel,"#ffbdbd"); var c=0.015 }
else if (pixel.temp < 5000) { pixel.color = pixelColorPick(pixel,"#ffd5bd"); var c=0.025 }
else if (pixel.temp < 7000) { pixel.color = pixelColorPick(pixel,"#ffffbd"); var c=0.05 }
else if (pixel.temp < 11000) { pixel.color = pixelColorPick(pixel,"#f7fff5"); var c=0.1 }
else if (pixel.temp < 28000) { pixel.color = pixelColorPick(pixel,"#bde0ff"); var c=0.2 }
else { pixel.color = pixelColorPick(pixel,"#c3bdff"); var c=0.4 }
for (var i = 0; i < adjacentCoords.length; i++) {
var x = pixel.x+adjacentCoords[i][0];
var y = pixel.y+adjacentCoords[i][1];
if (isEmpty(x,y)) {
if (Math.random() > c) {continue}
createPixel("light", x, y);
pixelMap[x][y].color = pixel.color;
}
else if (!outOfBounds(x,y)) {
var newPixel = pixelMap[x][y];
if (elements[newPixel.element].id === elements.sun.id) {
if (pixel.eclipse) { newPixel.eclipse = true }
if (pixel.temp!==newPixel.temp) {
var avg = (pixel.temp + newPixel.temp)/2;
pixel.temp = avg;
newPixel.temp = avg;
pixelTempCheck(pixel);
pixelTempCheck(newPixel);
}
}
}
}
},
tool: function(pixel) {
if (pixel.element === "light") {
deletePixel(pixel.x,pixel.y);
}
},
canPlace: true,
reactions: {
"hydrogen": { elem2:"helium", temp1:5 },
"helium": { elem2:"carbon_dioxide", temp1:5, tempMax:3600 },
"carbon_dioxide": { elem2:"neon", temp1:5, tempMax:1800 }
},
temp: 5504,
tempLow: -100,
stateLow: "supernova",
category: "special",
state: "gas",
//density: 1408,
insulate: true,
noMix: true,
alias: "star",
movable: false
},
"cell": {
color: ["#00ee00","#83ee00","#d6ee00"],
behavior: [
"XX|CL%0.5|XX",
"CL%0.5|XX|CL%0.5",
"M2%10|M1|M2%10",
],
reactions: {
"infection": { elem1:"infection", chance:0.015 },
"blood": { elem1:"blood", chance:0.01 },
"antibody": { elem1:"antibody", chance:0.01 },
"sugar": { elem2:"cell", chance:0.03 },
"sugar_water": { elem2:"cell", chance:0.04 },
"alcohol": { elem1:[null,"dna"], chance:0.02 },
"poison": { elem1:null, chance:0.02 },
"plague": { elem1:null, chance:0.02 },
"mercury": { elem1:null, chance:0.02 },
"chlorine": { elem1:null, chance:0.02 },
"cyanide": { elem1:null, chance:0.02 },
"soap": { elem1:null, chance:0.015 },
"oxygen": { elem2:"carbon_dioxide", chance:0.05 },
"ammonia": { elem2:"nitrogen", chance:0.05 },
"oil": { elem2:"methane", chance:0.001 }
},
tempHigh: 102,
stateHigh: ["steam","steam","steam","sugar"],
tempLow: -2,
stateLow: ["ice","ice","ice","sugar_ice"],
state: "solid",
density: 1000.1,
category: "life",
breakInto: ["water","dna","dna","dna"]
},
"cancer": {
color: ["#300b29","#5c114e","#870c71"],
behavior: [
"XX|CL%1|XX",
"CL%1|XX|CL%1",
"M2%2|M1|M2%2",
],
reactions: {
"cell": { elem2:"cancer", chance:0.005 },
"frog": { elem2:"cancer", chance:0.005 },
"tadpole": { elem2:"cancer", chance:0.005 },
"fish": { elem2:"cancer", chance:0.005 },
"rat": { elem2:"cancer", chance:0.005 },
"bird": { elem2:"cancer", chance:0.005 },
"bone": { elem2:"cancer", chance:0.005 },
"bone_marrow": { elem2:"cancer", chance:0.005 },
"skin": { elem2:"cancer", chance:0.005 },
"sugar": { elem2:"cancer", chance:0.04 },
"sugar_water": { elem2:"cancer", chance:0.05 },
"alcohol": { elem1:[null,"dna"], chance:0.01 },
"poison": { elem1:null, chance:0.01 },
"plant": { elem2:["dead_plant",null], chance:0.005 },
"grass": { elem2:["dead_plant",null], chance:0.005 },
"proton": { elem1:null, chance:0.04 },
"laser": { elem1:null, chance:0.04 }
},
tempHigh: 80,
stateHigh: "plague",
tempLow: -30,
stateLow: "dirty_water",
state: "solid",
density: 1000.2,
category: "life",
breakInto: "dna",
breakIntoColor: ["#c9b7b7","#c9c6b7","#c9c6b7","#b7c8c9","#c9b7c5"],
nocheer: true,
hidden: true
},
"dna": {
color: ["#ffe3e3","#e3e3ff","#ffffe3","#e3ffe3"],
behavior: behaviors.POWDER,
reactions: {
"fire": { elem2:null },
"radiation": { "color1":["#ffe3e3","#e3e3ff","#ffffe3","#e3ffe3"] },
"neutron": { "color1":["#ffe3e3","#e3e3ff","#ffffe3","#e3ffe3"] }
},
tempHigh: 190,
stateHigh: "smoke",
state: "solid",
density: 1700,
category: "life",
hidden: true,
alias: "deoxyribonucleic acid"
},
"plague": {
color: "#36005c",
behavior: [
"M2|M1|M2",
"M1|DL%1|M1",
"M2|M1|M2",
],
reactions: {
"frog": { elem2:"plague", chance:0.05 },
"ant": { elem2:"plague", chance:0.05 },
"bee": { elem2:"plague", chance:0.05 },
"fish": { elem2:"plague", chance:0.05 },
"firefly": { elem2:"plague", chance:0.05 },
"chlorine": { elem1:null },
"liquid_chlorine": { elem1:null },
"light": { elem1:null }
},
tempHigh: 300,
stateHigh: null,
category: "life",
state: "gas",
density: 600
},
"worm": {
color: "#d34c37",
behavior: [
"SW:dirt,sand,gravel,ash,mycelium,mud,wet_sand,clay_soil,water,salt_water,dirty_water,primordial_soup,blood,infection,color_sand%3|XX|SW:dirt,sand,gravel,ash,mycelium,mud,wet_sand,clay_soil,water,salt_water,dirty_water,primordial_soup,blood,infection,color_sand%3",
"M2%10|XX|M2%10",
"SW:dirt,sand,gravel,ash,mycelium,mud,wet_sand,clay_soil,water,salt_water,dirty_water,primordial_soup,blood,infection,color_sand%3|M1|SW:dirt,sand,gravel,ash,mycelium,mud,wet_sand,clay_soil,water,salt_water,dirty_water,primordial_soup,blood,infection,color_sand%3",
],
reactions: {
"ash": { elem2:[null,null,null,null,null,null,null,null,null,null,"dirt"], chance:0.1, func:behaviors.FEEDPIXEL },
"crumb": { elem2:[null,null,null,null,null,null,null,null,null,null,"dirt"], chance:0.1, func:behaviors.FEEDPIXEL },
"root": { elem2:"dirt", chance:0.1, func:behaviors.FEEDPIXEL },
"dead_plant": { elem2:"dirt", chance:0.1, func:behaviors.FEEDPIXEL },
"tinder": { elem2:[null,"dirt"], chance:0.1, func:behaviors.FEEDPIXEL },
"sawdust": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"dust": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"rotten_meat": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"dead_bug": { elem2:"dirt", chance:0.1, func:behaviors.FEEDPIXEL },
"hyphae": { elem2:"mycelium", chance:0.1, func:behaviors.FEEDPIXEL },
"plant": { elem2:"dirt", chance:0.01, func:behaviors.FEEDPIXEL },
"evergreen": { elem2:"dirt", chance:0.01, func:behaviors.FEEDPIXEL },
"herb": { elem2:"dirt", chance:0.1, func:behaviors.FEEDPIXEL },
"coffee_ground": { elem2:"dirt", chance:0.1, func:behaviors.FEEDPIXEL },
"nut": { elem2:"dirt", chance:0.05, func:behaviors.FEEDPIXEL },
"yolk": { elem2:null, chance:0.01, func:behaviors.FEEDPIXEL },
"charcoal": { elem2:"dirt", chance:0.05, func:behaviors.FEEDPIXEL },
"straw": { elem2:"dirt", chance:0.05, func:behaviors.FEEDPIXEL },
"mudstone": { elem2:"dirt", chance:0.1 },
"permafrost": { elem2:"dirt", chance:0.1 },
"packed_sand": { elem2:"sand", chance:0.1 },
"lichen": { elem2:"dirt", chance:0.0025 },
"salt": { elem1: "slime", elem2: null },
"potassium_salt": { elem1: "slime", elem2: null },
"epsom_salt": { elem1: "slime", elem2: null },
"alcohol": { elem1:null, chance:0.005 },
},
tempHigh: 100,
stateHigh: "ash",
tempLow: 0,
stateLow: "frozen_worm",
category:"life",
breakInto: "slime",
burn:20,
burnTime:50,
state: "solid",
density: 1050,
conduct: 0.17
},
"frozen_worm": {
color: "#37d3b6",
behavior: behaviors.STURDYPOWDER,
temp: -20,
tempHigh: 5,
stateHigh: "worm",
category:"life",
breakInto: "slime",
hidden: true,
state: "solid",
density: 1050,
conduct: 0.17
},
"flea": {
color: "#9e4732",
behavior: [
"M2|XX|M2",
"XX|XX|XX",
"M2|M1|M2",
],
reactions: {
"blood": { elem2:null, chance:0.1875, func:behaviors.FEEDPIXEL },
"infection": { elem2:null, chance:0.1875, func:behaviors.FEEDPIXEL },
"antibody": { elem2:null, chance:0.1874, func:behaviors.FEEDPIXEL },
"antidote": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"dead_plant": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"ketchup": { elem2:null, chance:0.1 },
"hair": { elem2:null, chance:0.01 },
"mercury": { elem2:null, elem1:null, chance:0.1875 },
"vinegar": { elem1:"dead_bug", elem2:null },
"alcohol": { elem1:"dead_bug", elem2:null },
"mayo": { elem1:"dead_bug", elem2:null, chance:0.025 }
},
tempHigh: 100,
stateHigh: "ash",
tempLow: 0,
stateLow: "dead_bug",
category:"life",
burn:95,
burnTime:25,
breakInto: ["dust","dead_bug"],
state: "solid",
density: 400,
conduct: 0.15
},
"termite": {
color: "#f5a056",
behavior: [
"XX|XX|SW:wood,tree_branch,dirt,sand,gravel,clay_soil%5",
"XX|FX%3|M2%15 AND BO",
"XX|M1|SW:wood,tree_branch,dirt,sand,gravel,clay_soil%5",
],
reactions: {
"wood": { elem2:null, chance:0.04, func:behaviors.FEEDPIXEL },
"tree_branch": { elem2:null, chance:0.02, func:behaviors.FEEDPIXEL },
"cellulose": { elem2:null, chance:0.04, func:behaviors.FEEDPIXEL },
"paper": { elem2:null, chance:0.04, func:behaviors.FEEDPIXEL },
"bamboo": { elem2:null, chance:0.03, func:behaviors.FEEDPIXEL },
"bamboo_plant": { elem2:null, chance:0.04, func:behaviors.FEEDPIXEL },
"sapling": { elem2:null, chance:0.025, func:behaviors.FEEDPIXEL },
"sawdust": { elem2:null, chance:0.025, func:behaviors.FEEDPIXEL },
"mulch": { elem2:"dirt", chance:0.025, func:behaviors.FEEDPIXEL },
"confetti": { elem2:null, chance:0.025, func:behaviors.FEEDPIXEL },
"wheat": { elem2:null, chance:0.025, func:behaviors.FEEDPIXEL },
"straw": { elem2:null, chance:0.025, func:behaviors.FEEDPIXEL },
"particleboard": { elem2:null, chance:0.025, func:behaviors.FEEDPIXEL },
"tinder": { elem2:null, chance:0.025, func:behaviors.FEEDPIXEL },
"lichen": { elem2:null, chance:0.025, func:behaviors.FEEDPIXEL },
"nut": { elem2:["nut_meat",null], chance:0.025, func:behaviors.FEEDPIXEL },
"vinegar": { elem1:"dead_bug", elem2:null },
"alcohol": { elem1:"dead_bug", elem2:null }
},
foodNeed: 20,
tempHigh: 100,
stateHigh: "ash",
tempLow: 0,
stateLow: "dead_bug",
category:"life",
burn:95,
burnTime:25,
breakInto: "dead_bug",
state: "solid",
conduct: 0.15
},
"ant": {
color: "#5e0b04",
behavior: behaviors.CRAWLER,
// behavior: [
// "XX|XX|SW:dirt,sand,gravel,clay_soil,mulch%8",
// "XX|FX%8|M2 AND BO",
// "XX|M1|SW:dirt,sand,gravel,clay_soil,mulch%8",
// ],
reactions: {
"wheat": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"caramel": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"bread": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"sugar_water": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"honey": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"soda": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"juice": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"sugar": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"rotten_meat": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"crumb": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"cheese": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"rotten_cheese": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"dead_bug": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"vinegar": { elem1:"dead_bug", elem2:null },
"alcohol": { elem1:"dead_bug", elem2:null },
"oil": { elem1:"dead_bug", chance:0.2 },
"mushroom_cap": { elem2:null, chance:0.025, func:behaviors.FEEDPIXEL },
"candy": { elem2:null, chance:0.025, func:behaviors.FEEDPIXEL },
"pumpkin": { elem2:null, chance:0.025, func:behaviors.FEEDPIXEL },
"pumpkin_seed": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"nut_butter": { elem2:null, chance:0.01, func:behaviors.FEEDPIXEL },
"jelly": { elem2:null, chance:0.02, func:behaviors.FEEDPIXEL },
},
tempHigh: 100,
stateHigh: "ash",
tempLow: 0,
stateLow: "dead_bug",
breakInto: "dead_bug",
category:"life",
burn:95,
burnTime:25,
state: "solid",
density: 500,
conduct: 0.15
},
"fly": {
color: "#4c4e42",
tick: behaviors.FLY,
behaviorOn: [
"XX|CR:flash|XX",
"CR:flash|CH:ash|CR:flash",
"XX|CR:flash|XX",
],
reactions: {
//"plant": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
//"evergreen": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"dead_plant": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"meat": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"cooked_meat": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"rotten_meat": { elem2:[null,null,"ammonia"], chance:0.15, func:behaviors.FEEDPIXEL },
"cheese": { elem2:[null,null,"ammonia"], chance:0.15, func:behaviors.FEEDPIXEL },
"rotten_cheese": { elem2:[null,null,"ammonia"], chance:0.15, func:behaviors.FEEDPIXEL },
"vine": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"corn": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"potato": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"crumb": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"wheat": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"yeast": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"caramel": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"bread": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"sugar_water": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"honey": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"soda": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL }
},
foodNeed: 15,
tempHigh: 100,
stateHigh: "ash",
tempLow: 0,
stateLow: "dead_bug",
breakInto: "dead_bug",
category:"life",
burn:95,
burnTime:25,
state: "solid",
density: 600,
conduct: 1
},
"firefly": {
color: ["#684841","#684841","#d9d950","#684841","#684841"],
tick: function(pixel) {
if (!pixel.fff) { // firefly flicker
// choose a number between 20 and 80
pixel.fff = Math.floor(Math.random() * 60) + 20;
}
if (pixelTicks % pixel.fff === 0) {
pixel.color = pixelColorPick(pixel,"#d9d950")
}
else if (pixelTicks % pixel.fff === 2) {
pixel.color = pixelColorPick(pixel,"#684841");
}
behaviors.FLY(pixel,function(firefly,newfly){
if (newfly) {
newfly.fff = firefly.fff;
}
})
},
reactions: {
"pollen": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"honey": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"firefly": { elem2:null, chance:0.01, func:behaviors.FEEDPIXEL },
"sugar_water": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"soda": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"sugar": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL }
},
tempHigh: 100,
stateHigh: "ash",
tempLow: 0,
stateLow: "dead_bug",
breakInto: "dead_bug",
category:"life",
burn:95,
burnTime:25,
state: "solid",
density: 600,
conduct: 0.15
},
"hive": {
color: "#a6a479",
tick: function(pixel) {
if (pixel.bees === undefined) {
pixel.bees = [];
}
else if (pixel.bees.length !== 0) {
if (pixel.temp < 33) { pixel.temp += 1 }
for (var i = 0; i < pixel.bees.length; i++) {
if (Math.random() > 0.25) { continue }
var bee = pixel.bees[i];
if (bee.pollen) {
bee.pollen = null;
pixel.honey++;
}
if (bee.queen && pixel.honey && Math.random() < 0.25) {
if (!bee.food) { bee.food = 1 }
else { bee.food++ }
}
var dirX = Math.floor(Math.random() * 3) - 1;
var dirY = Math.floor(Math.random() * 3) - 1;
if (isEmpty(pixel.x+dirX,pixel.y+dirY)) {
if (bee.queen) {
if (bee.mats) {
createPixel("hive",pixel.x+dirX,pixel.y+dirY);
pixelMap[pixel.x+dirX][pixel.y+dirY].hive = bee.hive;
bee.mats--;
}
else if (bee.food > 4) {
createPixel("bee",pixel.x+dirX,pixel.y+dirY);
pixelMap[pixel.x+dirX][pixel.y+dirY].hive = bee.hive;
bee.food = 0;
}
}
else {
bee.x = pixel.x+dirX;
bee.y = pixel.y+dirY;
delete bee.del;
pixelMap[pixel.x+dirX][pixel.y+dirY] = bee;
currentPixels.push(bee);
pixel.bees.splice(i,1);
i--;
}
}
else if (!outOfBounds(pixel.x+dirX,pixel.y+dirY)) {
var pixel2 = pixelMap[pixel.x+dirX][pixel.y+dirY];
if (pixel2.element === "hive" && pixel2.bees.length < 5) {
pixel2.bees.push(bee);
pixel.bees.splice(i,1);
i--;
}
}
}
}
if (pixel.honey && Math.random() < 0.01) {
if (!isEmpty(pixel.x,pixel.y+1,true) && pixelMap[pixel.x][pixel.y+1].element === "hive") {
pixelMap[pixel.x][pixel.y+1].honey ++;
pixel.honey --;
}
else if (isEmpty(pixel.x,pixel.y+1)) {
createPixel("honey",pixel.x,pixel.y+1);
pixel.honey --;
}
}
doDefaults(pixel);
},
hoverStat: function(pixel) { return pixel.bees.length + "bee" },
properties: {
bees: [],
hive: 0,
honey: 0
},
tempHigh: 300,
stateHigh: ["fire","fire","fire","ash"],
burn: 70,
burnTime: 300,
burnInto: ["fire","fire","fire","ash"],
breakInto: [null,null,"honey"],
category: "life",
state: "solid",
hidden: true,
movable: false
},
"bee": {
color: "#c4b100",
tick: function(pixel) {
if (pixelTicks-pixel.lastP > 150 && pixel.pollen && Math.random() < 0.0005 && isEmpty(pixel.x,pixel.y+1)) {
createPixel("pollen",pixel.x,pixel.y+1);
pixelMap[pixel.x][pixel.y+1].seed = pixel.pollen;
pixel.pollen = undefined;
}
behaviors.FLY(pixel,function(bee,hitPixel){
if (hitPixel) {
if (elements[hitPixel.element].seed === true) {
bee.pollen = hitPixel.element;
bee.lastP = pixelTicks
}
else if (elements[hitPixel.element].seed) {
bee.pollen = elements[hitPixel.element].seed;
bee.lastP = pixelTicks
}
if (hitPixel.lastP && (bee.lastP === undefined || bee.lastP < hitPixel.lastP)) {
bee.lastP = hitPixel.lastP
}
// BEE HIVE
if (bee.hive === undefined) {
if (hitPixel.hive !== undefined) { bee.hive = hitPixel.hive }
else if (Math.random() < 0.01 && eLists.HIVEPLACE.indexOf(hitPixel.element) !== -1) {
bee.queen = true;
bee.mats = Math.floor(Math.random() * 9) + 4; //from 3 to 10
bee.hive = Math.floor(Math.random() * 256);
deletePixel(bee.x,bee.y);
createPixel("hive",bee.x,bee.y);
pixelMap[bee.x][bee.y].hive = bee.hive;
pixelMap[bee.x][bee.y].bees.push(bee);
return;
}
}
else if (hitPixel.element === "hive" && hitPixel.bees.length < 5 && Math.random() < 0.25) {
deletePixel(bee.x,bee.y);
hitPixel.bees.push(bee);
return;
}
}
})
},
reactions: {
"sugar_water": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"soda": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"sugar": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"honey": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"yeast": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"caramel": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"candy": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"oil": { elem1:"dead_bug", chance:0.2 },
},
egg: "honey",
tempHigh: 100,
stateHigh: "ash",
tempLow: 0,
stateLow: "dead_bug",
breakInto: ["dead_bug","honey"],
category:"life",
burn:95,
burnTime:25,
state: "solid",
density: 600,
conduct: 0.15
},
"stink_bug": {
color: ["#56482d","#52472c","#635443"],
properties: {
"phase": 1
},
tick: function(pixel) {
var newX = pixel.x;
var newY = pixel.y;
if (pixel.phase === 1) { // Landing
newX += pixel.flipX ? -1 : 1;
newY ++;
if (!tryMove(pixel, newX, newY)) { pixel.phase = 0 } // Stop landing
}
else if (pixel.phase === 2) { // Flying
newX += pixel.flipX ? -1 : 1;
newY += Math.random() < 0.5 ? -1 : 1;
if (Math.random() < 0.01) { pixel.phase = 1 } // Start landing
if (!tryMove(pixel, newX, newY)) {
pixel.flipX = !pixel.flipX;
}
}
else if (pixel.phase === 0) { // Standing
if (Math.random() < 0.05) { newX += pixel.flipX ? -1 : 1; }
newY ++;
if (Math.random() < 0.01) { pixel.phase = 2 } // Start flying
tryMove(pixel, newX, newY);
}
// Random chance to flip
if (Math.random() < 0.05) { pixel.flipX = !pixel.flipX; }
// Random chance to create "stench" behind
if (Math.random() < 0.001) {
if (isEmpty(pixel.x+(pixel.flipX ? 1 : -1), pixel.y)) {
createPixel("stench",pixel.x+(pixel.flipX ? 1 : -1), pixel.y);
}
}
doHeat(pixel);
doElectricity(pixel);
},
reactions: {
"petal": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"pistil": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"grape": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"plant": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL }
},
flippableX: true,
tempHigh: 100,
stateHigh: "stench",
tempLow: 0,
stateLow: "dead_bug",
category:"life",
burn:95,
burnTime:25,
burnInto: "stench",
breakInto: ["stench","dead_bug"],
state: "solid",
density: 600,
conduct: 0.15
},
"dead_bug": {
color: ["#38302a","#403732","#453a2e","#241d15","#242e23"],
behavior: behaviors.POWDER,
tempHigh: 100,
stateHigh: "ash",
category:"life",
burn:95,
burnTime:25,
burnInto: ["smoke","smoke","ash"],
state: "solid",
density: 600,
hidden: true
},
"human": {
// color: ["#f5eac6","#d4c594","#a89160","#7a5733","#523018","#361e0e"],
color: ["#f3e7db","#f7ead0","#eadaba","#d7bd96","#a07e56","#825c43","#604134","#3a312a"],
category: "life",
properties: {
dead: false,
dir: 1,
panic: 0
},
tick: function(pixel) {
if (isEmpty(pixel.x, pixel.y+1)) {
createPixel("body", pixel.x, pixel.y+1);
pixel.element = "head";
}
else if (isEmpty(pixel.x, pixel.y-1)) {
createPixel("head", pixel.x, pixel.y-1);
pixelMap[pixel.x][pixel.y-1].color = pixel.color;
pixel.element = "body";
pixel.color = pixelColorPick(pixel)
}
else {
deletePixel(pixel.x, pixel.y);
}
},
related: ["body","head"],
cooldown: defaultCooldown,
forceSaveColor: true,
},
"body": {
color: ["#069469","#047e99","#7f5fb0"],
category: "life",
hidden: true,
density: 1500,
state: "solid",
conduct: .05,
temp: 37,
tempHigh: 250,
stateHigh: "cooked_meat",
tempLow: -30,
stateLow: "frozen_meat",
burn: 10,
burnTime: 250,
burnInto: "cooked_meat",
breakInto: ["blood","meat","bone"],
forceSaveColor: true,
reactions: {
"cancer": { elem1:"cancer", chance:0.005 },
"radiation": { elem1:["ash","meat","rotten_meat","cooked_meat"], chance:0.4 },
"neutron": { elem1:["ash","meat","rotten_meat","cooked_meat"], chance:0.01 },
"fallout": { elem1:["ash","meat","rotten_meat","cooked_meat"], chance:0.01 },
"plague": { elem1:"plague", chance:0.05 },
"egg": { elem2:"yolk", chance:0.5, oneway:true },
"grape": { elem2:"juice", chance:0.5, color2:"#291824", oneway:true },
"ant": { elem2:"dead_bug", chance:0.05, oneway:true },
"fly": { elem2:"dead_bug", oneway:true },
"firefly": { elem2:"dead_bug", oneway:true },
"bee": { elem2:"dead_bug", oneway:true },
"flea": { elem2:"dead_bug", oneway:true },
"termite": { elem2:"dead_bug", oneway:true },
"worm": { elem2:"slime", chance:0.05, oneway:true },
"stink_bug": { elem2:"stench", oneway:true },
"grass_seed": { elem2:null, chance:0.05 },
"gold_coin": { elem2:null, chance:0.05 },
},
properties: {
dead: false,
dir: 1,
panic: 0
},
tick: function(pixel) {
if (tryMove(pixel, pixel.x, pixel.y+1)) { // Fall
if (!isEmpty(pixel.x, pixel.y-2, true)) { // Drag head down
var headpixel = pixelMap[pixel.x][pixel.y-2];
if (headpixel.element == "head") {
if (isEmpty(pixel.x, pixel.y-1)) {
movePixel(pixelMap[pixel.x][pixel.y-2], pixel.x, pixel.y-1);
}
else {
swapPixels(pixelMap[pixel.x][pixel.y-2], pixelMap[pixel.x][pixel.y-1]);
}
}
}
}
doHeat(pixel);
doBurning(pixel);
doElectricity(pixel);
if (pixel.dead) {
// Turn into rotten_meat if pixelTicks-dead > 500
if (pixelTicks-pixel.dead > 200 && Math.random() < 0.1) {
changePixel(pixel,"rotten_meat");
}
return
}
// Find the head
if (!isEmpty(pixel.x, pixel.y-1, true) && pixelMap[pixel.x][pixel.y-1].element == "head") {
var head = pixelMap[pixel.x][pixel.y-1];
if (head.dead) { // If head is dead, kill body
pixel.dead = head.dead;
}
}
else { var head = null }
if (pixel.burning) {
pixel.panic += 0.1;
if (head && pixelTicks-pixel.burnStart > 240) {
pixel.color = head.color;
}
}
else if (pixel.panic > 0) {
pixel.panic -= 0.1;
}
if (isEmpty(pixel.x, pixel.y-1)) {
// create blood if decapitated 10% chance
if (Math.random() < 0.1 && !pixel.charge) {
createPixel("blood", pixel.x, pixel.y-1);
// set dead to true 15% chance
if (Math.random() < 0.15) {
pixel.dead = pixelTicks;
}
}
}
else if (head == null) { return }
else if (Math.random() < 0.1*(isEmpty(pixel.x, pixel.y+1) ? 1 : pixel.panic+1)) { // Move 10% chance
var movesToTry = [
[1*pixel.dir,0],
[1*pixel.dir,-1],
];
// While movesToTry is not empty, tryMove(pixel, x, y) with a random move, then remove it. if tryMove returns true, break.
while (movesToTry.length > 0) {
var move = movesToTry.splice(Math.floor(Math.random() * movesToTry.length), 1)[0];
if (isEmpty(pixel.x+move[0], pixel.y+move[1]-1)) {
var origx = pixel.x+move[0];
var origy = pixel.y+move[1];
if (tryMove(pixel, pixel.x+move[0], pixel.y+move[1]) && pixel.x===origx && pixel.y===origy) {
movePixel(head, head.x+move[0], head.y+move[1]);
break;
}
}
}
// 15% chance to change direction
if (Math.random() < 0.15) {
pixel.dir *= -1;
}
// homeostasis
if (pixel.temp > 37) { pixel.temp -= 1; }
else if (pixel.temp < 37) { pixel.temp += 1; }
}
}
},
"head": {
color: ["#f3e7db","#f7ead0","#eadaba","#d7bd96","#a07e56","#825c43","#604134","#3a312a"],
category: "life",
hidden: true,
density: 1080,
state: "solid",
conduct: .05,
temp: 37,
tempHigh: 250,
stateHigh: "cooked_meat",
tempLow: -30,
stateLow: "frozen_meat",
burn: 10,
burnTime: 250,
burnInto: "cooked_meat",
breakInto: ["blood","meat","bone"],
forceSaveColor: true,
reactions: {
"cancer": { elem1:"cancer", chance:0.005 },
"radiation": { elem1:["ash","meat","rotten_meat","cooked_meat"], chance:0.4 },
"neutron": { elem1:["ash","meat","rotten_meat","cooked_meat"], chance:0.03 },
"fallout": { elem1:["ash","meat","rotten_meat","cooked_meat"], chance:0.03 },
"plague": { elem1:"plague", chance:0.05 },
"oxygen": { elem2:"carbon_dioxide", chance:0.5 },
"meat": { elem2:null, chance:0.1 },
"cooked_meat": { elem2:null, chance:0.1 },
"cured_meat": { elem2:null, chance:0.1 },
"sugar": { elem2:null, chance:0.1 },
"broth": { elem2:null, chance:0.2 },
"yolk": { elem2:null, chance:0.1 },
"hard_yolk": { elem2:null, chance:0.1 },
"dough": { elem2:null, chance:0.1 },
"batter": { elem2:null, chance:0.2 },
"butter": { elem2:null, chance:0.1 },
"melted_butter": { elem2:null, chance:0.2 },
"chocolate": { elem2:null, chance:0.2 },
"melted_chocolate": { elem2:null, chance:0.3 },
"grape": { elem2:null, chance:0.1 },
"tomato": { elem2:null, chance:0.1 },
"herb": { elem2:null, chance:0.1 },
"lettuce": { elem2:null, chance:0.1 },
"corn": { elem2:null, chance:0.1 },
"popcorn": { elem2:null, chance:0.15 },
"potato": { elem2:null, chance:0.1 },
"baked_potato": { elem2:null, chance:0.15 },
"bread": { elem2:null, chance:0.1 },
"toast": { elem2:null, chance:0.1 },
"gingerbread": { elem2:null, chance:0.1 },
"baked_batter": { elem2:null, chance:0.2 },
"wheat": { elem2:null, chance:0.1 },
"candy": { elem2:null, chance:0.1 },
"yogurt": { elem2:null, chance:0.2 },
"frozen_yogurt": { elem2:null, chance:0.1 },
"ice_cream": { elem2:null, chance:0.2 },
"beans": { elem2:[null,null,null,null,null,null,null,null,"stench"], chance:0.2 },
"tea": { elem2:null, chance:0.2 },
"coffee": { elem2:null, chance:0.2 },
"milk": { elem2:null, chance:0.2 },
"cream": { elem2:null, chance:0.2 },
"soda": { elem2:null, chance:0.2 },
"chocolate_milk": { elem2:null, chance:0.2 },
"fruit_milk": { elem2:null, chance:0.2 },
"pilk": { elem2:null, chance:0.2 },
"eggnog": { elem2:null, chance:0.2 },
"juice": { elem2:null, chance:0.2 },
"cheese": { elem2:null, chance:0.1 },
"melted_cheese": { elem2:null, chance:0.2 },
"alcohol": { elem2:null, chance:0.2 },
"antidote": { elem2:null, chance:0.2 },
"honey": { elem2:null, chance:0.2 },
"caramel": { elem2:null, chance:0.2 },
"molasses": { elem2:null, chance:0.05 },
"ketchup": { elem2:null, chance:0.1 },
"pumpkin_seed": { elem2:null, chance:0.1 },
"nut": { elem2:null, chance:0.1 },
"nut_meat": { elem2:null, chance:0.1 },
"nut_butter": { elem2:null, chance:0.1 },
"nut_milk": { elem2:null, chance:0.2 },
"jelly": { elem2:null, chance:0.2 },
"mayo": { elem2:null, chance:0.2 },
"mashed_potato": { elem2:null, chance:0.2 },
"sauce": { elem2:null, chance:0.2 },
"pickle": { elem2:null, chance:0.1 },
},
properties: {
dead: false
},
tick: function(pixel) {
doHeat(pixel);
doBurning(pixel);
doElectricity(pixel);
if (pixel.dead) {
// Turn into rotten_meat if pixelTicks-dead > 500
if (pixelTicks-pixel.dead > 200 && Math.random() < 0.1) {
changePixel(pixel,"rotten_meat");
return
}
}
// Find the body
if (!isEmpty(pixel.x, pixel.y+1, true) && pixelMap[pixel.x][pixel.y+1].element == "body") {
var body = pixelMap[pixel.x][pixel.y+1];
if (body.dead) { // If body is dead, kill head
pixel.dead = body.dead;
}
}
else { var body = null }
if (tryMove(pixel, pixel.x, pixel.y+1)) {
// create blood if severed 10% chance
if (isEmpty(pixel.x, pixel.y+1) && !pixel.dead && Math.random() < 0.1 && !pixel.charge) {
createPixel("blood", pixel.x, pixel.y+1);
// set dead to true 15% chance
if (Math.random() < 0.15) {
pixel.dead = pixelTicks;
}
}
}
// homeostasis
if (pixel.temp > 37) { pixel.temp -= 1; }
else if (pixel.temp < 37) { pixel.temp += 1; }
}
},
"bird": {
color: "#997457",
properties: { "phase": 2, "rising":0 },
tick: function(pixel) {
var newX = pixel.x;
var newY = pixel.y;
if (pixel.phase === 1) { // Landing
newX += pixel.flipX ? -1 : 1;
newY += Math.random() < 0.5 ? 0 : 1;
if (!tryMove(pixel, newX, newY)) {
if (outOfBounds(newX, newY)) { pixel.phase = 0 }
else {
var newPixel = pixelMap[newX][newY];
if (elements[newPixel.element].state !== "solid") { pixel.phase = 3; }
else if (newPixel.element === "bird") {
pixel.phase = 3;
newPixel.phase = 3;
}
else { pixel.phase = 0; }
}
} // Stop landing
}
else if (pixel.phase === 2) { // Gliding
newX += pixel.flipX ? -1 : 1;
newY += Math.random() < 0.9 ? 0 : 1;
if (Math.random() < 0.01) { pixel.phase = 1 } // Start landing
if (!tryMove(pixel, newX, newY)) {
pixel.flipX = !pixel.flipX;
if (!outOfBounds(newX, newY) && pixelMap[newX][newY].element !== "bird") {
pixel.phase = 3;
}
}
}
else if (pixel.phase === 0) { // Standing
if (Math.random() < 0.05) { newX += pixel.flipX ? -1 : 1; }
newY ++;
if (Math.random() < 0.01) { pixel.phase = 3 } // Start rising
if (!tryMove(pixel, newX, newY)) {
if (!outOfBounds(newX, newY) && pixelMap[newX][newY].element === "bird") {
pixel.phase = 3;
pixelMap[newX][newY].phase = 3;
}
}
}
else if (pixel.phase === 3) { // Rising
newX += pixel.flipX ? -1 : 1;
newY --;
if (!tryMove(pixel, newX, newY) || (pixel.rising > 5 && Math.random() < 0.05)) { pixel.phase = 2; pixel.rising = 0; } // Start gliding
else { pixel.rising ++; }
}
doHeat(pixel);
doElectricity(pixel);
doBurning(pixel);
},
flippableX: true,
reactions: {
"fly": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"firefly": { elem2:null, chance:0.3, func:behaviors.FEEDPIXEL },
"bee": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"worm": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"ant": { elem2:null, chance:0.025, func:behaviors.FEEDPIXEL },
"dead_bug": { elem2:null, chance:0.04, func:behaviors.FEEDPIXEL },
"lichen": { elem2:null, chance:0.04, func:behaviors.FEEDPIXEL },
"termite": { elem2:null, chance:0.025, func:behaviors.FEEDPIXEL },
"flea": { elem2:null, chance:0.025, func:behaviors.FEEDPIXEL },
"mushroom_cap": { elem2:null, chance:0.025, func:behaviors.FEEDPIXEL },
"mushroom_gill": { elem2:null, chance:0.025, func:behaviors.FEEDPIXEL },
"seeds": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"flower_seed": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"wheat_seed": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"corn_seed": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"corn": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"potato_seed": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"grass_seed": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"crumb": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"pumpkin": { elem2:null, chance:0.025, func:behaviors.FEEDPIXEL },
"pumpkin_seed": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"coffee_bean": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"coffee_ground": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"nut": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"nut_meat": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"nut_butter": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"jelly": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"plague": { elem1:"plague", chance:0.05 },
"oxygen": { elem2:"carbon_dioxide", chance:0.5 }
},
foodNeed: 20,
temp: 41,
tempHigh: 120,
stateHigh: "cooked_meat",
stateHighColor: "#E4CFB9",
tempLow: -18,
stateLow: "frozen_meat",
category:"life",
burn:50,
burnTime:100,
breakInto: ["feather","blood"],
state: "solid",
density: 400,
conduct: 0.5
},
"rat": {
color: ["#a698a9","#8c7d82","#ccc3cf"],
behavior: [
"XX|CR:plague%0.05 AND M2%1.5|M2%5",
"XX|FX%2|M2 AND BO",
"XX|M1|M2",
],
reactions: {
"oxygen": { elem2:"carbon_dioxide", chance:0.5 },
"meat": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"cooked_meat": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"cheese": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"rotten_cheese": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"melted_cheese": { elem2:null, chance:0.3, func:behaviors.FEEDPIXEL },
"tomato": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"sauce": { elem2:null, chance:0.3, func:behaviors.FEEDPIXEL },
"plant": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"evergreen": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"algae": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"grass_seed": { elem2:null, chance:0.3 , func:behaviors.FEEDPIXEL},
"wheat_seed": { elem2:null, chance:0.3, func:behaviors.FEEDPIXEL },
"wheat": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"potato_seed": { elem2:null, chance:0.3, func:behaviors.FEEDPIXEL },
"potato": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"corn_seed": { elem2:null, chance:0.3, func:behaviors.FEEDPIXEL },
"corn": { elem2:null, chance:0.1 , func:behaviors.FEEDPIXEL},
"lichen": { elem2:null, chance:0.04, func:behaviors.FEEDPIXEL },
"flower_seed": { elem2:null, chance:0.4 , func:behaviors.FEEDPIXEL},
"flour": { elem2:null, chance:0.1 , func:behaviors.FEEDPIXEL},
"dough": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"bread": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"toast": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"gingerbread": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"yogurt": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"beans": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"salt": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"sugar": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"crumb": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"herb": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"salt_water": { elem2:"dirty_water", chance:0.2 },
"sugar_water": { elem2:"dirty_water", chance:0.2 },
"water": { elem2:"dirty_water", chance:0.2 },
"popcorn": { elem2:null, chance:0.3, func:behaviors.FEEDPIXEL },
"candy": { elem2:null, chance:0.3, func:behaviors.FEEDPIXEL },
"caramel": { elem2:null, chance:0.4, func:behaviors.FEEDPIXEL },
"lichen": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"egg": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"yolk": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"eggnog": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"milk": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"grape": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"batter": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"baked_batter": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"butter": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"melted_butter": { elem2:null, chance:0.3, func:behaviors.FEEDPIXEL },
"lettuce": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"baked_potato": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"ice_cream": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"cream": { elem2:null, chance:0.3, func:behaviors.FEEDPIXEL },
"pumpkin": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"pumpkin_seed": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"coffee_bean": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"coffee_ground": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"nut": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"nut_meat": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"nut_butter": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"jelly": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"worm": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"ant": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"frog": { elem2:null, chance:0.005, func:behaviors.FEEDPIXEL },
"snail": { elem2:"quicklime", chance:0.1, func:behaviors.FEEDPIXEL },
"slug": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
},
egg: "rat",
category: "life",
temp: 37.6,
tempHigh: 120,
stateHigh: "rotten_meat",
tempLow: -18,
stateLow: "frozen_meat",
breakInto: "infection",
burn:80,
burnTime:150,
state: "solid",
density: 1450,
conduct: 0.25
},
"frog": {
color: "#607300",
behavior: [
"XX|XX|M2%3 AND SW:water,salt_water,sugar_water,dirty_water,seltzer%7",
"XX|FX%0.5|CR:slime%0.01 AND BO",
"XX|M1|XX",
],
reactions: {
"fly": { elem2:null, chance:0.5, func:behaviors.FEEDPIXEL },
"firefly": { elem1:"meat", elem2:null, chance:0.5 },
"stinkbug": { elem2:null, chance:0.55, func:behaviors.FEEDPIXEL },
"snail": { elem2:"quicklime", chance:0.05, func:behaviors.FEEDPIXEL },
"slug": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"worm": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"algae": { elem2:null, chance:0.5, func:behaviors.FEEDPIXEL },
"oxygen": { elem2:"carbon_dioxide", chance:0.5 },
"dead_bug": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"mercury": { elem1:"rotten_meat", chance:0.1 },
"bleach": { elem1:"rotten_meat", chance:0.1 },
"infection": { elem1:"rotten_meat", chance:0.025 },
"uranium": { elem1:"rotten_meat", chance:0.1 },
"cyanide": { elem1:"rotten_meat", chance:0.1 },
"chlorine": { elem1:"meat", chance:0.1 },
"alcohol": { elem1:"meat", chance:0.025 },
"dirty_water": { elem1:"rotten_meat", chance:0.0001 },
"pool_water": { elem1:"rotten_meat", chance:0.005 },
"vinegar": { elem1:"rotten_meat", chance:0.001 },
},
foodNeed: 10,
baby: "tadpole",
temp: 19.1,
tempHigh: 100,
stateHigh: "cooked_meat",
tempLow: -18,
stateLow: "frozen_frog",
category:"life",
breakInto: "slime",
burn:15,
burnTime:300,
state: "solid",
density: 1450,
conduct: 0.2
},
"frozen_frog": {
color: "#007349",
behavior: behaviors.STURDYPOWDER,
temp: -20,
tempHigh: 5,
stateHigh: "frog",
category:"life",
breakInto: "slime",
hidden: true,
state: "solid",
density: 1500
},
"tadpole": {
color: "#87b574",
behavior: [
"XX|XX|M2%25 AND SW:water,salt_water,sugar_water,dirty_water,seltzer,pool_water%14",
"XX|FX%0.5|SW:water,salt_water,sugar_water,dirty_water,seltzer,pool_water%14",
"XX|M1|SW:water,salt_water,sugar_water,dirty_water,seltzer,pool_water%14",
],
tick: function(pixel) {
if (pixelTicks-pixel.start > 500) {
changePixel(pixel,"frog");
}
},
reactions: {
"algae": { elem2:null, chance:0.25 }
},
tempHigh: 100,
stateHigh: "steam",
tempLow: -10,
stateLow: "ice",
breakInto: ["slime",null],
category:"life",
hidden: true,
state: "solid",
density: 1450,
conduct: 0.2
},
"fish": {
color: "#ac8650",
behavior: [
"XX|M2%5|SW:water,salt_water,sugar_water,dirty_water,seltzer,pool_water,primordial_soup%14",
"XX|FX%0.5|BO",
"M2|M1|M2 AND SW:water,salt_water,sugar_water,dirty_water,seltzer,pool_water,primordial_soup%5",
],
reactions: {
"algae": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"plant": { elem2:null, chance:0.125, func:behaviors.FEEDPIXEL },
"fly": { elem2:null, chance:0.4, func:behaviors.FEEDPIXEL },
"firefly": { elem2:null, chance:0.6, func:behaviors.FEEDPIXEL },
"worm": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"tadpole": { elem2:null, chance:0.25, func:behaviors.FEEDPIXEL },
"oxygen": { elem2:"carbon_dioxide", chance:0.5 },
"dead_bug": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"broth": { elem2:"water", chance:0.2, func:behaviors.FEEDPIXEL },
"slug": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"herb": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"lettuce": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"dead_plant": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"lichen": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"yeast": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"yogurt": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"tea": { elem2:null, chance:0.2, func:behaviors.FEEDPIXEL },
"yolk": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"cell": { elem2:null, chance:0.15, func:behaviors.FEEDPIXEL },
"crumb": { elem2:null, chance:0.1, func:behaviors.FEEDPIXEL },
"alcohol": { elem1:"meat", chance:0.001 },
},
foodNeed: 20,
temp: 20,
tempHigh: 120,
stateHigh: "meat",
tempLow: -20,
stateLow: ["frozen_meat","frozen_meat","frozen_meat","frozen_fish"],
category:"life",
breakInto: "blood",
burn:20,
burnTime:200,
state: "solid",
density: 1080,
conduct: 0.2,
eggColor: ["#211316","#2C1A1D","#503734"]
},
"frozen_fish": {
color: "#50ac86",
behavior: behaviors.STURDYPOWDER,
temp: -20,
tempHigh: 5,
stateHigh: "fish",
category:"life",
breakInto: "blood",
hidden: true,
state: "solid",
density: 1050,
conduct: 0.17
},
"slug": {
color: ["#997e12","#997e12","#997e12","#997e12","#997e12","#997e12","#403314","#403314","#403314","#403314","#403314","#403314","#124a44"],
behavior: [
"XX|XX|XX",
"XX|FX%0.25|M2%0.5 AND BO",
"XX|M1|XX",
],
reactions: {
"salt": { elem1: "slime", elem2: null },
"potassium_salt": { elem1: "slime", elem2: null },
"epsom_salt": { elem1: "slime", elem2: null },
"plant": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"evergreen": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"cactus": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"dead_plant": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"worm": { elem2:null, chance:0.01, func:behaviors.FEEDPIXEL },
"mushroom_spore": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"grass": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"herb": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"lettuce": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"grass_seed": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"algae": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"mushroom_cap": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"mushroom_stalk": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"mushroom_gill": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"lichen": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"hyphae": { elem2:"dirt", chance:0.05, func:behaviors.FEEDPIXEL },
"mycelium": { elem2:"dirt", chance:0.05, func:behaviors.FEEDPIXEL },
"pumpkin": { elem2:null, chance:0.01, func:behaviors.FEEDPIXEL },
"grape": { elem2:null, chance:0.01, func:behaviors.FEEDPIXEL },
},
tempLow: 5,
stateLow: "slime",
tempHigh: 90,
stateHigh: "slime",
breakInto: "slime",
category: "life",
state: "solid",
density: 1450,
conduct: 0.17
},
"snail": {
color: "#5c3104",
behavior: [
"XX|XX|XX",
"XX|FX%0.25|M2%0.5 AND BO",
"XX|M1|XX",
],
reactions: {
"salt": { elem1: "quicklime", elem2: null },
"dirty_water": { elem2:"water", chance:0.05, func:behaviors.FEEDPIXEL },
"broth": { elem2:"water", chance:0.05, func:behaviors.FEEDPIXEL },
"tea": { elem2:"water", chance:0.05, func:behaviors.FEEDPIXEL },
"potassium_salt": { elem1: "quicklime", elem2: null },
"epsom_salt": { elem1: "quicklime", elem2: null },
"plant": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"evergreen": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"cactus": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"dead_plant": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"worm": { elem2:null, chance:0.01, func:behaviors.FEEDPIXEL },
"mushroom_spore": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"grass": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"herb": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"lettuce": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"grass_seed": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"algae": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"mushroom_cap": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"mushroom_stalk": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"mushroom_gill": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"lichen": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"hyphae": { elem2:"dirt", chance:0.05, func:behaviors.FEEDPIXEL },
"mycelium": { elem2:"dirt", chance:0.05, func:behaviors.FEEDPIXEL },
"pumpkin": { elem2:null, chance:0.01, func:behaviors.FEEDPIXEL },
"calcium": { elem2:null, chance:0.01, func:behaviors.FEEDPIXEL },
"limestone": { elem2:null, chance:0.001, func:behaviors.FEEDPIXEL },
"quicklime": { elem2:null, chance:0.01, func:behaviors.FEEDPIXEL },
"slaked_lime": { elem2:null, chance:0.01, func:behaviors.FEEDPIXEL },
"paper": { elem2:null, chance:0.01, func:behaviors.FEEDPIXEL },
"pickle": { elem2:null, chance:0.05, func:behaviors.FEEDPIXEL },
"grape": { elem2:null, chance:0.01, func:behaviors.FEEDPIXEL },
},
tempLow: -6.4,
stateLow: "quicklime",
tempHigh: 100,
stateHigh: "quicklime",
breakInto: ["slime","quicklime"],
category: "life",
state: "solid",
density: 1500,
conduct: 0.16
},
"burner": {
color: "#d6baa9",
behavior: [
"CR:propane|CR:propane|CR:propane",
"XX|XX|XX",
"XX|XX|XX",
],
category: "machines",
conduct: 0.73
},
"superheater": {
color: "#dd1111",
behavior: [
"XX|HT:10|XX",
"HT:10|XX|HT:10",
"XX|HT:10|XX",
],
category:"machines",
insulate:true
},
"freezer": {
color: "#1111dd",
behavior: [
"XX|CO:10|XX",
"CO:10|XX|CO:10",
"XX|CO:10|XX",
],
category:"machines",
insulate:true
},
"pipe": {
color: "#414c4f",
onSelect: function() {
logMessage("Draw a pipe, wait for walls to appear, then erase the exit hole.");
},
tick: function(pixel) {
if (!pixel.stage && pixelTicks-pixel.start > 60) {
for (var i = 0; i < squareCoords.length; i++) {
var coord = squareCoords[i];
var x = pixel.x+coord[0];
var y = pixel.y+coord[1];
if (!isEmpty(x,y,true) && elements[pixelMap[x][y].element].movable) {
deletePixel(x,y)
}
if (isEmpty(x,y)) {
createPixel("pipe_wall",x,y);
}
}
pixel.stage = 1;
}
else if (pixel.stage === 1 && pixelTicks-pixel.start > 70) { //uninitialized
for (var i = 0; i < adjacentCoords.length; i++) {
var coord = adjacentCoords[i];
var x = pixel.x+coord[0];
var y = pixel.y+coord[1];
if (isEmpty(x,y)) {
pixel.stage = 2; //blue
pixel.color = pixelColorPick(pixel,"#000036");
break;
}
}
}
else if (pixel.stage > 1 && pixelTicks % 3 === pixel.stage-2) { //initialized
for (var i = 0; i < squareCoords.length; i++) {
var coord = squareCoords[i];
var x = pixel.x+coord[0];
var y = pixel.y+coord[1];
if (!isEmpty(x,y,true) && pixelMap[x][y].element === "pipe") {
var newPixel = pixelMap[x][y];
if (newPixel.stage === 1) {
var newColor;
switch (pixel.stage) {
case 2: newPixel.stage = 3; newColor = "#003600"; break; //green
case 3: newPixel.stage = 4; newColor = "#360000"; break; //red
case 4: newPixel.stage = 2; newColor = "#000036"; break; //blue
}
newPixel.color = pixelColorPick(newPixel,newColor);
}
}
}
var moved = false;
shuffleArray(squareCoordsShuffle);
for (var i = 0; i < squareCoordsShuffle.length; i++) {
var coord = squareCoordsShuffle[i];
var x = pixel.x+coord[0];
var y = pixel.y+coord[1];
if (!isEmpty(x,y,true)) {
var newPixel = pixelMap[x][y];
if (newPixel.element === "pipe") {
var nextStage;
switch (pixel.stage) {
case 2: nextStage = 4; break; //green
case 3: nextStage = 2; break; //red
case 4: nextStage = 3; break; //blue
}
if (pixel.con && !newPixel.con && newPixel.stage === nextStage) { //transfer to adjacent pipe
newPixel.con = pixel.con;
newPixel.con.x = newPixel.x;
newPixel.con.y = newPixel.y;
pixel.con = null;
moved = true;
break;
}
}
else if (!pixel.con && elements[newPixel.element].movable) { //suck up pixel
pixel.con = newPixel;
deletePixel(newPixel.x,newPixel.y);
pixel.con.x = pixel.x;
pixel.con.y = pixel.y;
pixel.con.del;
moved = true;
break;
}
}
}
if (pixel.con && !moved) { // move to same stage if none other
for (var i = 0; i < squareCoordsShuffle.length; i++) {
var coord = squareCoordsShuffle[i];
var x = pixel.x+coord[0];
var y = pixel.y+coord[1];
if (isEmpty(x,y)) {
delete pixel.con.del;
pixel.con.x = x;
pixel.con.y = y;
pixelMap[x][y] = pixel.con;
currentPixels.push(pixel.con);
pixel.con = null;
break;
}
if (!isEmpty(x,y,true) && pixelMap[x][y].element === "pipe") {
var newPixel = pixelMap[x][y];
if (pixel.con && !newPixel.con && newPixel.stage === pixel.stage) {
newPixel.con = pixel.con;
newPixel.con.x = newPixel.x;
newPixel.con.y = newPixel.y;
pixel.con = null;
break;
}
}
}
}
}
doDefaults(pixel);
},
category: "machines",
movable: false,
canContain: true,
},
"pipe_wall": {
color: "#808080",
behavior: behaviors.WALL,
category: "machines",
noMix: true,
hidden: true
},
"ewall": {
color: "#7a7769",
behavior: behaviors.WALL,
category: "machines",
hardness: 1,
noMix: true,
conduct: 1
},
"torch": {
color: "#d68542",
behavior: [
"XX|CR:fire|XX",
"XX|XX|XX",
"XX|XX|XX",
],
reactions: {
"water": { elem1:"wood" },
"sugar_water": { elem1:"wood" },
"salt_water": { elem1:"wood" },
"seltzer": { elem1:"wood" },
"dirty_water": { elem1:"wood" },
"pool_water": { elem1:"wood" },
"steam": { elem1:"wood" },
"smog": { elem1:"wood" },
"rain_cloud": { elem1:"wood" },
"cloud": { elem1:"wood" },
"snow_cloud": { elem1:"wood" },
"hail_cloud": { elem1:"wood" },
"thunder_cloud": { elem1:"wood" },
"ice_nine": { elem1:"wood" }
},
temp:600,
category:"special",
breakInto: "sawdust",
tempLow: -273,
stateLow: "wood"
},
"spout": {
color: "#606378",
behavior: [
"XX|CR:water|XX",
"CR:water|XX|CR:water",
"XX|CR:water|XX",
],
category:"special",
tempHigh: 1455.5,
stateHigh: "molten_steel",
conduct: 0.42
},
"udder": {
color: "#ecb3f5",
tick: function(pixel) {
if (Math.random() <= 0.025 && isEmpty(pixel.x,pixel.y+1)) {
createPixel("milk",pixel.x,pixel.y+1);
pixelMap[pixel.x][pixel.y+1].temp = 38;
}
doDefaults(pixel);
},
tempHigh: 100,
stateHigh: "cooked_meat",
tempLow: -18,
stateLow: "frozen_meat",
burn:15,
burnTime:200,
burnInto:"cooked_meat",
category:"special",
movable: false,
},
"bone_marrow": {
color: "#c97265",
behavior: [
"XX|CR:blood,bone,bone%1|XX",
"CR:blood,bone,bone%1|XX|CR:blood,bone,bone%1",
"XX|CR:blood,bone,bone%1|XX",
],
category:"life",
tempHigh: 750,
stateHigh: ["quicklime","salt","steam","ash"],
tempLow: -10,
stateLow: "frozen_meat",
breakInto: ["quicklime","blood"],
hidden: true
},
"bone": {
color: "#d9d9d9",
behavior: behaviors.SUPPORT,
reactions: {
"blood": {elem1:"bone_marrow",chance:0.0005},
"antibody": {elem1:"bone_marrow",chance:0.0005},
"water": { elem2:"broth", tempMin:70 },
"salt_water": { elem2:"broth", tempMin:70 },
"sugar_water": { elem2:"broth", tempMin:70 },
"seltzer": { elem2:"broth", tempMin:70 },
},
category:"life",
tempHigh: 760,
stateHigh: "quicklime",
state: "solid",
density: 1900,
hardness: 0.5,
breakInto: ["quicklime","quicklime","quicklime","bone_marrow"]
},
"ball": {
color: "#e35693",
behavior: [
"XX|XX|XX",
"XX|FY:0%5|XX",
"XX|M1 AND BO|XX",
],
tempHigh: 250,
stateHigh: "molten_plastic",
category: "special",
flipY: false,
flippableY: true,
hidden: true
},
"balloon": {
color: ["#fe4a75","#267cb0","#1a743c","#ff6ffa","#eaede5","#1dc9f3","#ff0101","#f4cd32","#bee347","#fab937","#91c7cc"],
behavior: [
"M1%50|M1%50|M1%50",
"M2%5|XX|M2%5",
"M2%5|M2%5|M2%5",
],
reactions: {
"cloud": {elem1:"pop"},
"rain_cloud": {elem1:"pop"},
"snow_cloud": {elem1:"pop"},
"thunder_cloud": {elem1:"pop"},
"hail_cloud": {elem1:"pop"},
"acid_cloud": {elem1:"pop"},
"ozone": {elem1:"pop"},
},
category:"special",
tempHigh: 120,
stateHigh: "pop",
tempLow: -272.20,
stateLow: "pop",
burn: 20,
burnTime: 2,
burnInto: "pop",
state: "solid",
density: 0.164,
breakInto: ["confetti","helium","helium","helium"]
},
"antipowder": {
color: "#ebd1d8",
behavior: behaviors.AGPOWDER,
category:"special",
tempHigh: 1850,
stateHigh: "antimolten",
state: "solid",
density: 1850
},
"antimolten": {
color: ["#ffb5b5","#ffd0b5","#ffd0b5"],
behavior: [
"M1|M1|M1",
"M2|XX|M2",
"XX|CR:antifire%2.5|XX",
],
temp: 1850,
tempLow: 1750,
stateLow: "antipowder",
viscosity: 10000,
hidden: true,
state: "liquid",
density: 1000,
category: "special"
},
"antifire": {
color: ["#ffc3a6","#ffdfa3","#ffb69e"],
behavior: [
"XX|M2|XX",
"M2|XX|M2",
"M1|M1|M1",
],
reactions: {
"antifluid": { elem1: "antigas" },
"water": { elem1: "antigas" },
"steam": { elem1: "antigas" },
},
temp:600,
tempLow:100,
stateLow: "antigas",
tempHigh: 7000,
stateHigh: "plasma",
category: "special",
burning: true,
burnTime: 25,
burnInto: "antigas",
fireElement: "flash",
hidden: true,
state: "gas",
density: 0.2,
ignoreAir: true,
},
"antifluid": {
color: "#d1dbeb",
behavior: behaviors.AGLIQUID,
category:"special",
tempHigh: 100,
stateHigh: "antigas",
tempLow: 0,
stateLowName: "antiice",
state: "liquid",
density: 1000
},
"antigas": {
color: "#e6fffc",
behavior: [
"M2|M2|M2",
"M2|XX|M2",
"M1|M1|M1"
],
category:"special",
tempLow: 100,
stateLow: "antifluid",
tempHigh: 1000,
temp: 150,
stateHigh: "antifire",
hidden: true,
state: "gas",
density: 10
},
"vertical": {
color: "#d9d9d9",
behavior: [
"XX|M1|XX",
"CR:wall|XX|CR:wall",
"XX|XX|XX",
],
reactions: {
"electric": { elem1:"horizontal" },
},
category:"special",
hidden:true,
excludeRandom: true
},
"horizontal": {
color: "#d9d9d9",
behavior: [
"XX|CR:wall|XX",
"XX|XX|M1",
"XX|CR:wall|XX",
],
reactions: {
"proton": { elem1:"vertical" },
"positron": { elem1:"vertical" },
},
category:"special",
hidden:true,
excludeRandom: true
},
"ash": {
color: ["#8c8c8c","#9c9c9c"],
behavior: behaviors.POWDER,
reactions: {
"steam": { elem1: "pyrocumulus", chance:0.08, "y":[0,12], "setting":"clouds" },
"rain_cloud": { elem1: "pyrocumulus", chance:0.08, "y":[0,12], "setting":"clouds" },
"cloud": { elem1: "pyrocumulus", chance:0.08, "y":[0,12], "setting":"clouds" },
"snow_cloud": { elem1: "pyrocumulus", chance:0.08, "y":[0,12], "setting":"clouds" },
"hail_cloud": { elem1: "pyrocumulus", chance:0.08, "y":[0,12], "setting":"clouds" },
"thunder_cloud": { elem1: "pyrocumulus", chance:0.08, "y":[0,12], "setting":"clouds" },
"acid_cloud": { elem1: "pyrocumulus", chance:0.05, "y":[0,12], "setting":"clouds" },
"pyrocumulus": { elem1: "pyrocumulus", chance:0.08, "y":[0,12], "setting":"clouds" },
"stench": { elem2:null, chance:0.1 }
},
category:"powders",
state: "solid",
density: 700,
tempHigh: 2000,
forceAutoGen: true,
stateHigh: ["molten_ash","smoke","smoke","smoke"]
},
"molten_ash": {
tempHigh: 3550,
stateHigh: "smoke"
},
"light": {
color: "#fffdcf",
tick: function(pixel) {
if (Math.random() < 0.02) {
deletePixel(pixel.x,pixel.y);
return;
}
if (pixel.bx===undefined) {
// choose 1, 0, or -1
pixel.bx = Math.random() < 0.5 ? 1 : Math.random() < 0.5 ? 0 : -1;
pixel.by = Math.random() < 0.5 ? 1 : Math.random() < 0.5 ? 0 : -1;
// if both are 0, make one of them 1 or -1
if (pixel.bx===0 && pixel.by===0) {
if (Math.random() < 0.5) { pixel.bx = Math.random() < 0.5 ? 1 : -1; }
else { pixel.by = Math.random() < 0.5 ? 1 : -1; }
}
}
// move and invert direction if hit
if (pixel.bx && !tryMove(pixel, pixel.x+pixel.bx, pixel.y)) {
var newX = pixel.x + pixel.bx;
if (!isEmpty(newX, pixel.y, true)) {
var newPixel = pixelMap[pixel.x+pixel.bx][pixel.y];
if (!elements[newPixel.element].insulate) {
newPixel.temp += 1;
pixelTempCheck(newPixel);
}
if (!elements.light.reactions[newPixel.element]) {
pixel.color = newPixel.color;
}
}
pixel.bx = -pixel.bx;
}
if (pixel.by && !tryMove(pixel, pixel.x, pixel.y+pixel.by)) {
var newY = pixel.y + pixel.by;
if (!isEmpty(pixel.x, newY, true)) {
var newPixel = pixelMap[pixel.x][pixel.y+pixel.by];
if (!elements[newPixel.element].insulate) {
newPixel.temp += 1;
pixelTempCheck(newPixel);
}
if (!elements.light.reactions[newPixel.element]) {
pixel.color = newPixel.color;
}
}
pixel.by = -pixel.by;
}
},
reactions: {
"glass": { "color1":["#ff0000","#ff8800","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff"] },
"glass_shard": { "color1":["#ff0000","#ff8800","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff"] },
"rad_glass": { "color1":["#9f6060","#9f8260","#9f9f60","#609f60","#609f9f","#60609f","#9f609f"] },
"rad_shard": { "color1":["#9f6060","#9f8260","#9f9f60","#609f60","#609f9f","#60609f","#9f609f"] },
"steam": { "color1":["#ff0000","#ff8800","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff"] },
"rain_cloud": { "color1":["#ff0000","#ff8800","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff"] },
"cloud": { "color1":["#ff0000","#ff8800","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff"] },
"smog": { "color1":["#9f6060","#9f8260","#9f9f60","#609f60","#609f9f","#60609f","#9f609f"] },
"ice": { "color1":"#c2fff9" },
"rime": { "color1":"#c2fff9" },
"water": { "color1":"#a1bac9" },
"salt_water": { "color1":"#a1bac9" },
"sugar_water": { "color1":"#a1bac9" },
"dirty_water": { "color1":"#a1c9a8" },
"seltzer": { "color1":"#c2fff9" },
"diamond": { "color1":["#c2c5ff","#c2d9ff"] },
"rainbow": { "color1":["#ff0000","#ff8800","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff"] },
"static": { "color1":["#ffffff","#bdbdbd","#808080","#424242","#1c1c1c"] }
},
temp: 35,
tempLow: -273,
stateLow: ["liquid_light",null],
stateLowColorMultiplier: 0.8,
category: "energy",
state: "gas",
density: 0.00001,
ignoreAir: true,
insulate: true
},
"liquid_light": {
color: "#bdbc9d",
//behavior: behaviors.SUPERFLUID,
tick: function(pixel) {
if (Math.random() < 0.0002) {
deletePixel(pixel.x,pixel.y);
return;
}
if (pixel.charge && elements[pixel.element].behaviorOn) {
pixelTick(pixel)
}
if (Math.random() < 0.33) { tryMove(pixel, pixel.x, pixel.y+1) }
if (!isEmpty(pixel.x, pixel.y+1)) {
// go either left or right depending on pixel.flipX
var newx = pixel.flipX ? pixel.x-1 : pixel.x+1;
if (Math.random() < 0.5) {
if (!tryMove(pixel, newx, pixel.y)) {
if (!outOfBounds(newx, pixel.y) && !elements.liquid_light.reactions[pixelMap[newx][pixel.y].element]) {
pixel.color = pixelMap[newx][pixel.y].color;
}
pixel.flipX = !pixel.flipX;
if (!tryMove(pixel, newx, pixel.y+1) && !outOfBounds(newx, pixel.y+1) && !elements.liquid_light.reactions[pixelMap[newx][pixel.y+1].element]) {
pixel.color = pixelMap[newx][pixel.y+1].color;
}
}
}
else {
if (!tryMove(pixel, newx, pixel.y+1)) {
if (!outOfBounds(newx, pixel.y+1) && !elements.liquid_light.reactions[pixelMap[newx][pixel.y+1].element]) {
pixel.color = pixelMap[newx][pixel.y+1].color;
}
if (!tryMove(pixel, newx, pixel.y)) {
pixel.flipX = !pixel.flipX;
if (!outOfBounds(newx, pixel.y) && !elements.liquid_light.reactions[pixelMap[newx][pixel.y].element]) {
pixel.color = pixelMap[newx][pixel.y].color;
}
}
}
}
}
doDefaults(pixel);
},
reactions: {
"glass": { "color1":["#ff0000","#ff8800","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff"] },
"glass_shard": { "color1":["#ff0000","#ff8800","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff"] },
"rad_glass": { "color1":["#9f6060","#9f8260","#9f9f60","#609f60","#609f9f","#60609f","#9f609f"] },
"rad_shard": { "color1":["#9f6060","#9f8260","#9f9f60","#609f60","#609f9f","#60609f","#9f609f"] },
"steam": { "color1":["#ff0000","#ff8800","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff"] },
"rain_cloud": { "color1":["#ff0000","#ff8800","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff"] },
"cloud": { "color1":["#ff0000","#ff8800","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff"] },
"smog": { "color1":["#9f6060","#9f8260","#9f9f60","#609f60","#609f9f","#60609f","#9f609f"] },
},
temp: -273,
tempHigh: -272,
stateHigh: "light",
category: "energy",
state: "gas",
density: 0.00002,
ignoreAir: true,
viscosity: 0,
insulate: true,
hidden: true
},
"laser": {
color: "#ff0000",
behavior: [
"XX|XX|XX",
"XX|DL%0.25|XX",
"XX|XX|XX",
],
tick: behaviors.BOUNCY,
temp: 35,
tempLow: -273,
stateLow: ["liquid_light",null],
stateLowColorMultiplier: 0.8,
breakInto: "light",
breakIntoColor: "#ffcfcf",
category: "energy",
state: "gas",
density: 0.00001,
ignoreAir: true
},
"pointer": {
color: "#ff0000",
tick: function(pixel) {
if (pixelTicks - pixel.start > 1) {
deletePixel(pixel.x, pixel.y)
}
},
tool: function(pixel) {
if (pixel.element === "pointer") {
pixel.start = pixelTicks;
}
},
canPlace: true,
category:"special",
customColor: true,
hidden:true,
movable: false,
state: "gas",
glow: false,
density: 1,
},
"charcoal": {
color: "#2b2b2b",
behavior: behaviors.POWDER,
reactions: {
"broth": { elem2:"water", chance:0.02 },
"tea": { elem2:"water", chance:0.02 },
},
burn: 25,
burnTime: 1000,
burnInto: ["fire","fire","fire","fire","ash","carbon_dioxide"],
category: "powders",
state: "solid",
density: 208,
breakInto: ["ash","ash","carbon_dioxide"],
hardness: 0.5,
conduct: 0.001
},
"tinder": {
color: ["#917256","#87684f","#735f4a","#5d4c3e","#4b3a2e"],
behavior: behaviors.STURDYPOWDER,
category: "powders",
tempHigh: 400,
stateHigh: "fire",
burn: 50,
burnTime: 100,
state: "solid",
density: 23
},
"sawdust": {
color: ["#dec150","#c7b15a"],
behavior: behaviors.POWDER,
reactions: {
"water": { elem1:"cellulose", elem2:null },
"dirty_water": { elem1:"cellulose", elem2:null },
"salt_water": { elem1:"cellulose", elem2:null },
"sugar_water": { elem1:"cellulose", elem2:null },
"honey": { elem1:"particleboard", elem2:null },
"glue": { elem1:"particleboard", elem2:null }
},
tempHigh: 400,
stateHigh: "fire",
category: "powders",
burn: 25,
burnTime: 150,
burnInto: ["ash","fire","fire","fire"],
state: "solid",
density: 393
},
"hail": {
color: "#c5e9f0",
tick: function(pixel) {
for (var i=0; i<3; i++) {
if (!tryMove(pixel, pixel.x, pixel.y+1)) {
if (!isEmpty(pixel.x, pixel.y+1,true)) {
var newPixel = pixelMap[pixel.x][pixel.y+1];
if (newPixel.element === "hail") { break; }
if (elements[newPixel.element].state == "solid") {
if (Math.random() > (elements[newPixel.element].hardness || 0)) {
if (elements[newPixel.element].breakInto) {
breakPixel(newPixel);
}
else {
deletePixel(newPixel.x, newPixel.y);
}}}}
deletePixel(pixel.x,pixel.y);
break;
}}},
temp: -20,
tempHigh: 10,
stateHigh: "water",
category: "powders",
state: "solid",
density: 850,
insulate: true,
hidden: true
},
"hydrogen": {
color: "#558bcf",
behavior: behaviors.GAS,
reactions: {
"oxygen": { elem1:null, elem2:"steam", tempMin:500 },
"hydrogen": { elem1:"neutron", elem2:"helium", tempMin:10000, temp1:20000, temp2:20000 },
"nitrogen": { elem1:null, elem2:"oxygen", tempMin:10000 },
"sulfur": { elem1:null, elem2:"chlorine", tempMin:10000 },
"neon": { elem1:null, elem2:"sodium", tempMin:10000 },
"fire": { elem1:"explosion", chance:0.005 },
},
category: "gases",
burn: 100,
burnTime: 2,
burnInto: ["fire","fire","fire","fire","fire","fire","fire","fire","fire","fire","fire","fire","steam"],
tempLow: -253,
stateLow: "liquid_hydrogen",
state: "gas",
density: 0.08375,
conduct: 0.02,
colorOn: "#E515D6"
},
"oxygen": {
color: "#99c7ff",
behavior: behaviors.GAS,
reactions: {
"copper": { elem1:null, elem2:"oxidized_copper", chance:0.05 },
"bronze": { elem1:null, elem2:"oxidized_copper", chance:0.025 },
"iron": { elem1:null, elem2:"rust", chance:0.025 },
"steel": { elem1:null, elem2:"rust", chance:0.02 },
"water": { elem1:"foam" },
"salt_water": { elem1:"foam" },
"sugar_water": { elem1:"foam" },
"seltzer": { elem1:"foam" },
"soda": { elem1:"foam" },
"dirty_water": { elem1:"foam" },
"oxygen": { elem1: null, elem2: "ozone", chance:0.3, "y":[0,12], "setting":"clouds" },
"ozone": { elem1: "ozone", chance:0.4, "y":[0,12], "setting":"clouds" },
"light": { elem1: "ozone", elem2: null, chance:0.3, "y":[0,12], "setting":"clouds" },
},
category: "gases",
// burn: 100,
// burnTime: 2,
tempLow: -183.94,
stateLow: "liquid_oxygen",
state: "gas",
density: 1.292
},
"nitrogen": {
color: "#b8d1d4",
behavior: behaviors.GAS,
reactions: {
"oxygen": { elem1:null, elem2:"anesthesia", tempMin:250 },
"hydrogen": { elem1:null, elem2:"ammonia" },
"neon": { elem1:null, elem2:"chlorine", tempMin:10000 }
},
category: "gases",
tempLow: -195.8,
stateLow: "liquid_nitrogen",
state: "gas",
density: 1.165
},
"helium": {
color: "#a69494",
behavior: behaviors.GAS,
category: "gases",
tempLow: -272.20,
stateLow: "liquid_helium",
state: "gas",
density: 0.1786,
conduct: 0.02,
colorOn: "#ff4c24"
},
"anesthesia": {
color: "#d3e1e3",
behavior: behaviors.GAS,
category: "gases",
tempHigh: 600,
stateHigh: ["oxygen","fire"],
tempLow: -88.48,
stateLow: ["nitrogen","oxygen"],
hidden: true,
state: "gas",
density: 1.9781,
alias: ["nitrous oxide","anaesthesia","anesthetic"]
},
"carbon_dioxide": {
color: "#2f2f2f",
behavior: behaviors.GAS,
reactions: {
"plant": { elem1:"oxygen" },
"evergreen": { elem1:"oxygen" },
"grass": { elem1:"oxygen" },
"cactus": { elem1:"oxygen" },
"bamboo": { elem1:"oxygen" },
"bamboo_plant": { elem1:"oxygen" },
"vine": { elem1:"oxygen" },
"flower_seed": { elem1:"oxygen" },
"grass_seed": { elem1:"oxygen" },
"algae": { elem1:"oxygen" }
},
category: "gases",
tempLow: -78.5,
stateLow: "dry_ice",
state: "gas",
density: 1.977,
alias: ["CO2","CO₂"]
},
"bubble": {
color: "#afc7fa",
behavior: behaviors.BUBBLE,
category: "gases",
state: "gas",
breakInto: null,
tempHigh: 200,
stateHigh: null,
tempLow: -10,
stateLow: null,
density: 1.294,
stain: -0.1
},
"ammonia": {
color: "#bab6a9",
behavior: behaviors.GAS,
reactions: {
"methane": { elem1:["hydrogen","water"], elem2:"cyanide_gas", chance:0.25 },
"plant": { elem1:"plant", chance:0.05 },
"evergreen": { elem1:"evergreen", chance:0.05 },
"cactus": { elem1:"cactus", chance:0.05 },
"wheat_seed": { elem1:"wheat", chance:0.05 },
"grass": { elem1:"grass", chance:0.05 },
"grass_seed": { elem1:"grass", chance:0.05 },
"bamboo_plant": { elem1:"bamboo", chance:0.05 },
"flower_seed": { elem1:"flower_seed", chance:0.05 },
"petal": { elem1:"flower_seed", chance:0.05 },
"vine": { elem1:"vine", chance:0.05 },
"sapling": { elem1:"tree_branch", chance:0.05 },
"tree_branch": { elem1:"tree_branch", chance:0.05 },
"corn_seed": { elem1:"corn", chance:0.05 },
"root": { elem1:"root", chance:0.05 },
"dirt": { elem1:"grass", chance:0.05 },
"mud": { elem1:"grass", chance:0.05 },
"water": { elem1:"algae", chance:0.005 },
"potato_seed": { elem1:"potato", chance:0.05 },
"pumpkin_seed": { elem1:"pumpkin", chance:0.05 },
"herb": { elem1:"herb", chance:0.05 },
"lettuce": { elem1:"lettuce", chance:0.05 },
"yeast": { elem1:"yeast", chance:0.05 },
"fish": { elem2:"meat", chance:0.05 },
"bird": { elem2:"meat", chance:0.05 },
"frog": { elem2:"meat", chance:0.05 },
"rat": { elem2:"rotten_meat", chance:0.05 },
},
tempLow: -33.34,
category: "gases",
state: "gas",
density: 0.73
},
"liquid_ammonia": {
tempLow: -77.78,
density: 681.9,
},
"oil": {
color: "#470e00",
behavior: behaviors.LIQUID,
tick: function(pixel) {
if (!pixel.burning && pixel.temp > 90 && Math.random() < 0.001) {
if (pixel.temp < 150) { changePixel(pixel,"propane") }
else if (pixel.temp < 300) { changePixel(pixel,"molten_plastic") }
else { changePixel(pixel,"lamp_oil") }
}
},
reactions: {
"dirt": { elem1:null, elem2:"mud" },
"sand": { elem1:null, elem2:"wet_sand" },
"sulfur": { elem1:null, elem2:"greek_fire" },
"molten_sulfur": { elem1:"greek_fire", elem2:"greek_fire" },
},
category: "liquids",
tempHigh: 500,
stateHigh: "fire",
burn: 70,
burnTime: 300,
burnInto: ["carbon_dioxide","fire"],
viscosity: 250,
state: "liquid",
density: 825,
stain: 0.05,
alias: "petroleum"
},
"lamp_oil": {
color: "#b3b38b",
behavior: behaviors.LIQUID,
tick: function(pixel) {
if (pixel.temp > 500 && !pixel.burning) {
pixel.burning = true;
pixel.burnStart = pixelTicks;
}
},
reactions: {
"glue": {elem2:null, chance:0.05},
"wax": {elem2:null, chance:0.005},
"melted_wax": {elem2:null, chance:0.025},
},
category: "liquids",
tempHigh: 2100,
stateHigh: "fire",
burn: 95,
burnTime: 2000,
burnInto: ["carbon_dioxide","fire"],
viscosity: 3,
state: "liquid",
density: 850,
alias: "kerosene"
},
"propane": {
color: "#cfcfcf",
behavior: behaviors.GAS,
behaviorOn: [
"XX|XX|XX",
"XX|CH:fire|XX",
"XX|XX|XX",
],
conduct: 0.01,
category: "gases",
tempHigh: 600,
stateHigh: "fire",
tempLow: -43,
burn: 100,
burnTime: 5,
fireColor: ["#00ffff","#00ffdd"],
state: "gas",
density: 2.0098,
alias: "gas"
},
"liquid_propane": {
tempHigh: -40,
stateHigh: "propane",
tempLow: -188
},
"methane": {
color: "#9f9f9f",
behavior: behaviors.GAS,
behaviorOn: [
"XX|XX|XX",
"XX|CH:fire|XX",
"XX|XX|XX",
],
conduct: 0.01,
category: "gases",
tempHigh: 400,
stateHigh: "fire",
tempLow: -161.5,
burn: 85,
burnTime: 5,
fireColor: ["#00ffff","#00ffdd"],
state: "gas",
density: 0.554
},
"liquid_methane": {
"tempLow": -182
},
"stained_glass": {
color: ["#6b2e2e","#6b4f2e","#6b6b2e","#2e6b2e","#2e6b6b","#2e2e6b","#6b2e6b"],
behavior: behaviors.WALL,
tick: function(pixel) {
if (pixel.start-1 <= pixelTicks) {
pixel.color = "hsl(" + (pixel.colorstart || pixel.start) + ",40%,30%)";
if (!pixel.colorstart) {
pixel.colorstart = pixel.start;
}
}
},
tempHigh: 1500,
category: "solids",
state: "solid",
density: 2500,
breakInto: "color_sand",
noMix: true,
movable: false,
},
"molten_stained_glass": {
color: ["#c27070","#c29c70","#c2c270","#70c270","#70c2c2","#7070c2","#c270c2"],
tick: function(pixel) {
if (pixel.start-1 <= pixelTicks) {
pixel.color = "hsl(" + (pixel.colorstart || pixel.start) + ",40%,60%)";
if (!pixel.colorstart) {
pixel.colorstart = pixel.start;
}
}
}
},
"art": {
color: "#ffffff",
behavior: behaviors.WALL,
customColor: true,
category: "special"
},
"rainbow": {
color: ["#ff0000","#ff8800","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff"],
tick: function(pixel) {
var t = pixelTicks+pixel.x+pixel.y;
var r = Math.floor(127*(1-Math.cos(t*Math.PI/90)));
var g = Math.floor(127*(1-Math.cos(t*Math.PI/90+2*Math.PI/3)));
var b = Math.floor(127*(1-Math.cos(t*Math.PI/90+4*Math.PI/3)));
pixel.color = "rgb("+r+","+g+","+b+")";
},
category: "special",
movable: false,
breakInto: "static"
},
"static": {
color: ["#ffffff","#888888","#000000"],
behavior: [
"XX|XX|XX",
"XX|CC:ffffff,9c9c9c,454545|XX",
"XX|XX|XX",
],
category: "special",
conduct: 1,
movable: false,
},
"border": {
color: "#00ffff",
tick: function(pixel) {
var t = pixelTicks/2+pixel.x+pixel.y;
var r = Math.floor(127*Math.sin(t/1.5));
pixel.color = "rgba("+r+","+r*2+","+r*2+","+r/127+")";
},
category: "special",
hardness: 1,
insulate: true,
movable: false,
},
"clay": {
color: "#d4c59c",
behavior: behaviors.SUPPORT,
reactions: {
"dirt": { elem1:"clay_soil", elem2:"clay_soil" },
"gravel": { elem1:"clay_soil", elem2:"clay_soil" },
},
tempHigh: 135,
stateHigh: "baked_clay",
tempLow: -50,
stateLow: "clay_soil",
category: "land",
state: "solid",
density: 1760
},
"clay_soil": {
color: ["#f49a6f","#ab7160","#b56c52"],
behavior: [
"XX|XX|XX",
"XX|XX|XX",
"M2%25|M1|M2%25",
],
tempHigh: 140,
stateHigh: "brick",
category: "land",
state: "solid",
density: 1600
},
"brick": {
color: "#cb4141",
colorPattern: textures.BRICK,
colorKey: {
"r": "#cb4141",
"w": "#bababa"},
behavior: behaviors.WALL,
category: "solids",
tempHigh: 1540,
state: "solid",
density: 1650,
hardness: 0.33,
breakInto: "brick_rubble"
},
"ruins": {
color: "#5c5c5c",
behavior: [
"XX|SP|XX",
"XX|XX|XX",
"M2%1|M1|M2%1"
],
tempHigh: 1500,
stateHigh: "magma",
category:"solids",
state: "solid",
density: 2400,
hardness: 0.33,
breakInto: "dust"
},
"porcelain": {
color: "#e1e4dd",
behavior: behaviors.WALL,
category: "solids",
state: "solid",
density: 2403,
hardness: 0.4,
breakInto: "porcelain_shard",
noMix: true,
},
"sapling": {
color: "#3e9c3e",
tick: function(pixel) {
if (!tryMove(pixel,pixel.x,pixel.y+1)) {
if (Math.random() < 0.02 && pixel.age > 50 && pixel.temp < 100) {
if (!outOfBounds(pixel.x,pixel.y+1)) {
var dirtPixel = pixelMap[pixel.x][pixel.y+1];
if (dirtPixel && (eLists.SOIL.indexOf(dirtPixel.element) !== -1 || dirtPixel.element === "grass")) {
changePixel(dirtPixel,"root");
}
}
if (isEmpty(pixel.x,pixel.y-1)) {
if (!pixel.wc) {
var c = Math.random();
if (c < 0.01) { pixel.wc="#632e1f"; pixel.lc="#ff7ad3" } //cherry
else if (c < 0.05) { pixel.wc="#632a0d"; pixel.lc="#d5ebce" } //white
else if (c < 0.1) { pixel.wc="#4a2818"; pixel.lc="#990000" } //red
else if (c < 0.2) { pixel.wc="#5c311f"; pixel.lc="#c24008" } //fall
else if (c < 0.3) { pixel.wc="#824427"; pixel.lc="#b58b0d" } //gold
else if (c < 0.4) { pixel.wc="#471b05"; pixel.lc="#157515" } //dark
else if (c < 0.45) { pixel.wc="#a0522d"; pixel.lc="#51a953" } //pale
else if (c < 0.5) { pixel.wc="#c2c1ba"; pixel.lc="#7ab31e" } //birch
else { pixel.wc="#a0522d"; pixel.lc="#00bf00" } //basic
pixel.color = pixelColorPick(pixel, pixel.lc);
}
movePixel(pixel,pixel.x,pixel.y-1);
createPixel(Math.random() > 0.5 ? "wood" : "tree_branch",pixel.x,pixel.y+1);
pixelMap[pixel.x][pixel.y+1].wc = pixel.wc;
pixelMap[pixel.x][pixel.y+1].lc = pixel.lc;
pixelMap[pixel.x][pixel.y+1].color = pixelColorPick(pixelMap[pixel.x][pixel.y+1], pixel.wc);
}
}
else if (pixel.age > 1000 && Math.random() < 0.05) {
changePixel(pixel,"wood");
pixel.color = pixelColorPick(pixel, pixel.wc);
}
pixel.age++;
}
doDefaults(pixel);
},
properties: {
"age":0
},
tempHigh: 100,
stateHigh: "dead_plant",
tempLow: -2,
stateLow: "frozen_plant",
burn: 65,
burnTime: 15,
category: "life",
state: "solid",
density: 1500,
cooldown: defaultCooldown,
seed: true
},
"pinecone": {
color: ["#5c3e33","#472f27","#31211b"],
tick: function(pixel) {
if (!tryMove(pixel,pixel.x,pixel.y+1) && pixelTicks-pixel.start > 50) {
if (pixel.h === undefined) { // set to even number between 6 and 20
pixel.h = Math.floor(Math.random()*7)*2+6;
}
if (Math.random() < 0.02 && pixel.h > 0 && pixel.temp < 100) {
if (!outOfBounds(pixel.x,pixel.y+1)) { // grow roots
var dirtPixel = pixelMap[pixel.x][pixel.y+1];
if (dirtPixel && (eLists.SOIL.indexOf(dirtPixel.element) !== -1 || dirtPixel.element === "grass")) {
changePixel(dirtPixel,"root");
}
}
if (isEmpty(pixel.x,pixel.y-1) && tryMove(pixel,pixel.x,pixel.y-1)) {
if (pixel.h % 2 && pixel.h < 12) {
createPixel("evergreen",pixel.x,pixel.y+1);
pixelMap[pixel.x][pixel.y+1].h = pixel.h;
}
else {
createPixel("wood",pixel.x,pixel.y+1);
}
pixel.h --;
}
}
else if (pixel.h === 0) {
changePixel(pixel,"evergreen");
}
}
doDefaults(pixel);
},
tempHigh: 500,
stateHigh: "wood",
burn: 5,
burnTime: 100,
category: "life",
state: "solid",
density: 1500,
cooldown: defaultCooldown,
seed: true
},
"evergreen": {
color: "#006300",
tick: function (pixel) {
if (pixel.h > 0 && pixelTicks % (50+pixel.h) === 0) {
// extend to the left and right, giving the next evergreen h-1
if (isEmpty(pixel.x-1,pixel.y)) {
createPixel("evergreen",pixel.x-1,pixel.y);
pixelMap[pixel.x-1][pixel.y].h = pixel.h-2;
}
if (isEmpty(pixel.x+1,pixel.y)) {
createPixel("evergreen",pixel.x+1,pixel.y);
pixelMap[pixel.x+1][pixel.y].h = pixel.h-2;
}
}
doDefaults(pixel);
},
reactions: {
"vinegar": { elem1:"dead_plant", elem2:null, chance:0.035 },
"baking_soda": { elem1:"dead_plant", elem2:null, chance:0.01 },
"bleach": { elem1:"dead_plant", elem2:null, chance:0.05 },
"alcohol": { elem1:"dead_plant", elem2:null, chance:0.035 }
},
category:"life",
tempHigh: ["dead_plant","dead_plant","dead_plant","dead_plant","pinecone"],
stateHigh: "dead_plant",
burn:45,
burnTime:75,
burnInto: ["dead_plant","dead_plant","dead_plant","dead_plant","pinecone"],
breakInto: ["dead_plant","dead_plant","dead_plant","dirt","sap"],
state: "solid",
density: 1050,
seed: "pinecone",
hidden: true,
movable: false
},
"cactus": {
color: ["#78a33e","#84b543","#cce37b","#84b543","#78a33e"],
tick: function(pixel) {
if (!pixel.stage) {
if (!tryMove(pixel,pixel.x,pixel.y+1)) {
if (Math.random() < 0.02 && isEmpty(pixel.x,pixel.y-1)) {
createPixel("cactus",pixel.x,pixel.y-1);
pixelMap[pixel.x][pixel.y-1].stage = 0;
pixelMap[pixel.x][pixel.y-1].h = (pixel.h||0)+1;
pixel.stage = 1;
}
else if (Math.random() < 0.0025) {
pixel.stage = 2;
if (Math.random() < 0.25) {
pixel.color = pixelColorPick(pixel, "#E0007B")
}
}
}
}
else if (pixel.stage === 1) { // create sides or stop
if (Math.random() < 0.02) {
if (Math.random() < 0.15 && pixel.h) { // create side
var nx = pixel.x + (Math.random() < 0.5 ? -1 : 1);
if (isEmpty(nx,pixel.y)) {
createPixel("cactus",nx,pixel.y);
pixelMap[nx][pixel.y].stage = 3;
pixel.stage = 2;
}
}
else {
pixel.stage = 2; // do nothing
}
}
}
else if (pixel.stage === 3) { // just grow one to the side
if (Math.random() < 0.02) {
var nx = null;
if (isEmpty(pixel.x+1,pixel.y)) { nx=pixel.x+1; }
else if (isEmpty(pixel.x-1,pixel.y)) { nx=pixel.x-1; }
if (nx) {
createPixel("cactus",nx,pixel.y);
pixelMap[nx][pixel.y].stage = 4;
}
}
}
else if (pixel.stage === 4) { // grow a bit
if (Math.random() < 0.02) {
if (Math.random() < 0.66) { // grow up
if (isEmpty(pixel.x,pixel.y-1) && isEmpty(pixel.x,pixel.y-2)) {
createPixel("cactus",pixel.x,pixel.y-1);
pixelMap[pixel.x][pixel.y-1].stage = 4;
pixel.stage = 2;
}
}
else {
pixel.stage = 2; // do nothing
}
}
}
doDefaults(pixel);
},
reactions: {
"water": { elem2:null, chance:0.01 },
"vinegar": { elem1:"dead_plant", elem2:null, chance:0.035 },
"baking_soda": { elem1:"dead_plant", elem2:null, chance:0.01 },
"bleach": { elem1:"dead_plant", elem2:null, chance:0.05 },
"alcohol": { elem1:"dead_plant", elem2:null, chance:0.035 }
},
tempHigh: 250,
stateHigh: ["dead_plant","dead_plant","dead_plant","dead_plant","dead_plant","steam"],
tempLow: -5,
stateLow: "frozen_plant",
breakInto: [null,null,null,"sap"],
breakIntoColor: "#D7E1D9",
burn: 10,
burnTime: 300,
category: "life",
state: "solid",
density: 600,
cooldown: defaultCooldown,
seed: true
},
"seeds": {
color: ["#359100","#74b332","#b9d461","#dede7a"],
tick: function(pixel) {
// Choose randomly from eLists.SEEDS
changePixel(pixel,eLists.SEEDS[Math.floor(Math.random()*eLists.SEEDS.length)]);
},
category: "life",
cooldown: defaultCooldown,
seed: true
},
"grass_seed": {
color: ["#439809","#258b08","#118511","#127b12","#136d14"],
behavior: [
"XX|M2%0.05|XX",
"XX|L2:grass|XX",
"XX|M1|XX",
],
tempHigh: 100,
stateHigh: "dead_plant",
tempLow: -2,
stateLow: "frozen_plant",
burn: 50,
burnTime: 20,
category: "life",
state: "solid",
density: 1400,
breakInto: null,
hidden: true,
cooldown: defaultCooldown,
seed: true
},
"wheat_seed": {
color: "#b6c981",
behavior: [
"XX|M2%0.25|XX",
"XX|L2:wheat AND C2:wheat%30|XX",
"XX|M1|XX",
],
tempHigh: 400,
stateHigh: "fire",
tempLow: -2,
stateLow: "frozen_plant",
burn: 50,
burnTime: 20,
breakInto: null,
category: "life",
state: "solid",
density: 769,
hidden: true,
cooldown: defaultCooldown,
seed: true
},
"straw": {
color: ["#e9d391","#a3835e","#b79a73"],
behavior: behaviors.WALL,
tempHigh: 400,
stateHigh: "fire",
burn: 30,
burnTime: 200,
burnInto: ["smoke","smoke","smoke","smoke","ash"],
breakInto: "flour",
category: "solids",
state: "solid",
density: 67.5
},
"paper": {
color: "#f0f0f0",
behavior: behaviors.WALL,
reactions: {
"water": { elem1:"cellulose", elem2:null },
"dirty_water": { elem1:"cellulose", elem2:null },
"salt_water": { elem1:"cellulose", elem2:null },
"sugar_water": { elem1:"cellulose", elem2:null },
"seltzer": { elem1:"cellulose", elem2:null },
"soda": { elem1:"cellulose", elem2:null },
"blood": { elem1:"cellulose", elem2:null },
"foam": { elem1:"cellulose", elem2:null },
"bubble": { elem1:"cellulose", elem2:null },
"oil": { elem1:"cellulose", elem2:null },
"alcohol": { elem1:"cellulose", elem2:null },
"vinegar": { elem1:"cellulose", elem2:null },
"light": { stain1:"#ebdfa7" },
"oxygen": { stain1:"#ebdfa7" }
},
tempHigh: 248,
stateHigh: ["fire","fire","fire","fire","fire","ash"],
burn: 70,
burnTime: 300,
burnInto: ["fire","fire","fire","fire","fire","ash"],
category: "solids",
state: "solid",
density: 1201
},
"pollen": {
color: "#ffffc0",
tick: function(pixel) {
if (Math.random() < 0.01 && !isEmpty(pixel.x,pixel.y+1,true)) {
if (Math.random() < 0.5 && eLists.SOIL.indexOf(pixelMap[pixel.x][pixel.y+1].element) !== -1) {
changePixel(pixel,pixel.seed||"flower_seed");
}
else {
deletePixel(pixel.x,pixel.y)
return;
}
}
behaviors.POWDER(pixel);
},
reactions: {
"sugar_water": { elem1: null, elem2: "honey" },
"water": { elem1: null },
"salt_water": { elem1: null },
"dirty_water": { elem1: null },
"seltzer": { elem1: null },
"pool_water": { elem1: null },
},
category:"life",
tempHigh: 400,
stateHigh: "ash",
burn:50,
burnTime:20,
breakInto: [null,null,"dust"],
state: "solid",
density: 1435
},
"flower_seed": {
color: "#0e990e",
behavior: [
"XX|M2%1.5|XX",
"XX|L2:plant AND C2:pistil%30|XX",
"XX|M1|XX",
],
tempHigh: 100,
stateHigh: "dead_plant",
tempLow: -2,
stateLow: "frozen_plant",
burn:50,
burnTime:20,
breakInto: null,
category:"life",
state: "solid",
density: 1400,
cooldown: defaultCooldown,
seed: true
},
"pistil": {
color: ["#734e39","#2f0603","#d2ac3a","#8a978f","#593117"],
tick: function(pixel) {
if (!pixel.fColor) {
// make it a hsl random hue, 100% saturation, 50% lightness
pixel.fColor = "hsl(" + Math.floor(Math.random()*360) + ",100%,"+ (Math.floor(Math.random() * (95 - 24)) + 25) +"%)";
}
var coordsToCheck = [
[pixel.x-1,pixel.y],
[pixel.x+1,pixel.y],
[pixel.x,pixel.y-1],
[pixel.x,pixel.y+1],
]
// check if each pixel is empty, if it is create a petal with the color fColor
for (var i = 0; i < coordsToCheck.length; i++) {
var coord = coordsToCheck[i];
if (isEmpty(coord[0],coord[1])) {
createPixel("petal",coord[0],coord[1]);
pixelMap[coord[0]][coord[1]].color = pixel.fColor;
}
}
doDefaults(pixel)
},
tempHigh: 100,
stateHigh: "dead_plant",
tempLow: -2,
stateLow: "frozen_plant",
burn:50,
burnTime:20,
category:"life",
hidden: true,
movable: false,
state: "solid",
density: 1400,
breakInto: "dead_plant",
seed: "flower_seed",
forceSaveColor: true
},
"petal": {
color: ["#ff0000","#ff8800","#ffff00","#88ff00","#00ff00","#00ff88","#00ffff","#0088ff","#0000ff","#8800ff","#ff00ff"],
behavior: [
"XX|ST:pistil|XX",
"ST:pistil|FX%0.25|ST:pistil",
"M2%10|ST:pistil AND M1%10|M1%10",
],
reactions: {
"water": { elem2:"tea", tempMin:80, color2:"#9e4c00" },
"salt_water": { elem2:"tea", tempMin:80, color2:"#9e4c00" },
"sugar_water": { elem2:"tea", tempMin:80, color2:"#9e4c00" },
"seltzer": { elem2:"tea", tempMin:80, color2:"#9e4c00" },
},
tempHigh: 100,
stateHigh: "dead_plant",
tempLow: -2,
stateLow: "frozen_plant",
burn:50,
burnTime:20,
category:"life",
state: "solid",
density: 1400,
seed: "flower_seed",
forceSaveColor: true
},
"tree_branch": {
color: "#a0522d",
tick: function(pixel) {
if (!pixel.burning) {
if (!pixel.lc) { pixel.lc = "#00bf00" }
if (!pixel.wc) { pixel.wc = "#a0522d" }
if (isEmpty(pixel.x-1,pixel.y-1) && Math.random() < 0.02) {
if (Math.random() < 0.5) {
createPixel("plant",pixel.x-1,pixel.y-1);
pixelMap[pixel.x-1][pixel.y-1].color = pixelColorPick(pixelMap[pixel.x-1][pixel.y-1], pixel.lc);
}
else {
createPixel("tree_branch",pixel.x-1,pixel.y-1);
pixelMap[pixel.x-1][pixel.y-1].color = pixelColorPick(pixelMap[pixel.x-1][pixel.y-1], pixel.wc);
pixelMap[pixel.x-1][pixel.y-1].wc = pixel.wc;
pixelMap[pixel.x-1][pixel.y-1].lc = pixel.lc;
}
}
if (isEmpty(pixel.x+1,pixel.y-1) && Math.random() < 0.02) {
if (Math.random() < 0.5) {
createPixel("plant",pixel.x+1,pixel.y-1);
pixelMap[pixel.x+1][pixel.y-1].color = pixelColorPick(pixelMap[pixel.x+1][pixel.y-1], pixel.lc);
}
else {
createPixel("tree_branch",pixel.x+1,pixel.y-1);
pixelMap[pixel.x+1][pixel.y-1].color = pixelColorPick(pixelMap[pixel.x+1][pixel.y-1], pixel.wc);
pixelMap[pixel.x+1][pixel.y-1].wc = pixel.wc;
pixelMap[pixel.x+1][pixel.y-1].lc = pixel.lc;
}
}
if (isEmpty(pixel.x,pixel.y-1) && Math.random() < 0.02) {
if (Math.random() < 0.75) {
createPixel("plant",pixel.x,pixel.y-1);
pixelMap[pixel.x][pixel.y-1].color = pixelColorPick(pixelMap[pixel.x][pixel.y-1], pixel.lc);
}
else {
createPixel("tree_branch",pixel.x,pixel.y-1);
pixelMap[pixel.x][pixel.y-1].color = pixelColorPick(pixelMap[pixel.x][pixel.y-1], pixel.wc);
pixelMap[pixel.x][pixel.y-1].wc = pixel.wc;
pixelMap[pixel.x][pixel.y-1].lc = pixel.lc;
}
}
}
doDefaults(pixel);
},
movable: false,
tempHigh: 100,
stateHigh: "wood",
tempLow: -30,
stateLow: "wood",
category: "life",
burn: 2,
burnTime: 300,
burnInto: ["sap","ember","charcoal","smoke"],
hidden: true,
state: "solid",
density: 1500,
hardness: 0.15,
breakInto: ["sap","sawdust"],
seed: "sapling",
forceSaveColor: true
},
"vine": {
color: "#005900",
tick: function(pixel) {
doDefaults(pixel);
if (pixel.start === pixelTicks && pixel.fruit === undefined && !pixel.stop) {
if (Math.random() < 0.1) {
pixel.fruit = Math.random() < 0.5 ? "grape" : "tomato";
}
else { pixel.fruit = null }
}
if (isEmpty(pixel.x,pixel.y-1)) {
pixel.sp = 0; //not supported
}
else if (!outOfBounds(pixel.x,pixel.y-1) && pixelMap[pixel.x][pixel.y-1].element === "vine" && pixelMap[pixel.x][pixel.y-1].sp === 0) {
pixel.sp = 0;
}
else { pixel.sp = 1 } //supported
if (pixel.stop) {
if (pixel.sp === 0) { tryMove(pixel, pixel.x, pixel.y+1); }
return;
}
if (pixel.sp === 0) { tryMove(pixel, pixel.x, pixel.y+1); }
else {
if (pixel.fert && pixel.stage && Math.random() < 0.01 && isEmpty(pixel.x,pixel.y+1)) {
clonePixel(pixel,pixel.x,pixel.y+1);
pixelMap[pixel.x][pixel.y+1].fert = true;
pixelMap[pixel.x][pixel.y+1].stage = pixel.stage-1;
}
}
if (pixel.fert===undefined) { // able to grow down
pixel.fert = Math.random() < 0.50;
}
if (pixel.stage===undefined) {
pixel.stage = Math.floor(Math.random()*20)+10;
}
if (Math.random() < 0.03 && isEmpty(pixel.x-1,pixel.y) && !isEmpty(pixel.x-1,pixel.y-1) && (outOfBounds(pixel.x-1,pixel.y-1) || pixelMap[pixel.x-1][pixel.y-1].element !== "vine")) {
createPixel("vine",pixel.x-1,pixel.y);
pixelMap[pixel.x-1][pixel.y].fruit = pixel.fruit;
}
if (Math.random() < 0.03 && isEmpty(pixel.x+1,pixel.y) && !isEmpty(pixel.x+1,pixel.y-1) && (outOfBounds(pixel.x+1,pixel.y-1) || pixelMap[pixel.x+1][pixel.y-1].element !== "vine")) {
createPixel("vine",pixel.x+1,pixel.y);
pixelMap[pixel.x+1][pixel.y].fruit = pixel.fruit;
}
if (Math.random() < 0.03 && isEmpty(pixel.x,pixel.y-1) && (
(!isEmpty(pixel.x-1,pixel.y-1) && (outOfBounds(pixel.x-1,pixel.y-1) || pixelMap[pixel.x-1][pixel.y-1].element !== "vine")) ||
(!isEmpty(pixel.x+1,pixel.y-1) && (outOfBounds(pixel.x+1,pixel.y-1) || pixelMap[pixel.x+1][pixel.y-1].element !== "vine")))
) {
createPixel("vine",pixel.x,pixel.y-1);
pixelMap[pixel.x][pixel.y-1].fruit = pixel.fruit;
}
if (pixel.sp === 1) {
if (pixel.fruit && Math.random() < 0.01) {
for (var i = 0; i < adjacentCoords.length; i++) {
var coords = adjacentCoords[i];
var x = pixel.x + coords[0];
var y = pixel.y + coords[1];
if (isEmpty(x,y)) {
createPixel(pixel.fruit,x,y)
break;
}
}
}
}
},
tempHigh: 100,
stateHigh: "dead_plant",
tempLow: -2,
stateLow: "frozen_plant",
burn: 35,
burnTime: 100,
breakInto: "dead_plant",
category: "life",
state: "solid",
density: 1050,
seed: "vine",
ignore: ["vine"]
},
"bamboo_plant": {
color: ["#fbc882","#dfad64"],
behavior: [
"XX|M2%2|XX",
"XX|L2:bamboo AND C2:bamboo%10|XX",
"XX|M1|XX",
],
tempHigh: 100,
stateHigh: "dead_plant",
tempLow: -2,
stateLow: "bamboo",
burn: 30,
burnTime: 100,
category: "life",
state: "solid",
density: 686,
breakInto: "sawdust",
cooldown: defaultCooldown,
seed: true
},
"foam": {
color: "#cad2e3",
behavior: behaviors.FOAM,
tick: function(pixel) {
if (pixel.foam && isEmpty(pixel.x,pixel.y-1)) {
createPixel("foam",pixel.x,pixel.y-1);
pixel.foam--;
pixelMap[pixel.x][pixel.y-1].foam = pixel.foam;
pixelMap[pixel.x][pixel.y-1].temp = pixel.temp;
}
},
category: "liquids",
state: "gas",
tempLow: -78.5,
stateLow: null,
density: 40,
stain: -0.1,
extinguish: true
},
"acid": {
color: ["#b5cf91","#a1ff5e","#288f2a"],
behavior: [
"XX|DB%5|XX",
"DB%5 AND M2|XX|DB%5 AND M2",
"DB%5 AND M2|DB%10 AND M1|DB%5 AND M2",
],
ignore: ["glass","rad_glass","glass_shard","rad_shard","stained_glass","baked_clay","acid_gas","neutral_acid","acid_cloud","water","salt_water","sugar_water","dirty_water","copper","gold","porcelain","plastic","bead","microplastic","molten_plastic","pool_water","chlorine","hydrogen","gold_coin","silver","nickel","calcium","bone"],
reactions: {
"ash": { elem1:"neutral_acid", elem2:null },
"limestone": { elem1:"neutral_acid", elem2:null },
"quicklime": { elem1:"neutral_acid", elem2:null },
"slaked_lime": { elem1:"neutral_acid", elem2:null },
"borax": { elem1:"neutral_acid", elem2:null },
"ammonia": { elem1:"neutral_acid", elem2:null },
"bleach": { elem1:"neutral_acid", elem2:null },
"caustic_potash": { elem1:"water", elem2:"potassium_salt" },
"bone": { elem1:"neutral_acid", chance:0.01 },
"water": { elem1:null, elem2:"dirty_water" },
"salt_water": { elem1:null, elem2:"water" },
"sugar_water": { elem1:null, elem2:"water" },
"plant": { elem1:null, elem2:"dead_plant" },
"tree_branch": { elem1:null, elem2:"wood" },
"charcoal": { elem1:null, elem2:"carbon_dioxide" },
"rock": { elem1:null, elem2:"sand", chance:0.05 },
"baking_soda": { elem1:"salt_water", elem2:["carbon_dioxide","foam"] },
"calcium": { elem1:"chlorine", elem2:"hydrogen", chance:0.01 },
"zinc": { elem1:"hydrogen", elem2:null, chance:0.03 },
"sugar": { elem1:"steam", elem2:"carbon_dioxide" },
},
category: "liquids",
tempHigh: 110,
stateHigh: "acid_gas",
tempLow: -58.88,
burn: 30,
burnTime: 1,
state: "liquid",
density: 1049,
stain: -0.1,
alias: "hydrochloric acid"
},
"neutral_acid": {
color: ["#c8d9b0","#c1d9b0","#b8dbb9"],
behavior: behaviors.LIQUID,
reactions: {
"bone": { elem2:"glue", tempMin:60, chance:0.005 },
},
category: "liquids",
state: "liquid",
tempHigh: 110,
stateHigh: "hydrogen",
density: 1020,
hidden: true
},
"acid_gas": {
color: ["#85a758","#3b7810","#256626"],
behavior: [
"M1|DB%5 AND M1|M1",
"DB%5 AND M1|XX|DB%5 AND M1",
"DB%5 AND M1|DB%10 AND M1|DB%5 AND M1",
],
ignore: ["glass","rad_glass","glass_shard","rad_shard","stained_glass","baked_clay","acid_gas","neutral_acid","acid_cloud","water","salt_water","sugar_water","dirty_water","copper","gold","porcelain","plastic","bead","microplastic","molten_plastic","pool_water","chlorine","hydrogen","gold_coin","silver","nickel","calcium","bone"],
reactions: {
"acid_gas": { elem1: null, elem2: "acid_cloud", chance:0.3, "y":[0,12], "setting":"clouds" },
"rain_cloud": { elem1: null, elem2: "acid_cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"cloud": { elem1: null, elem2: "acid_cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"snow_cloud": { elem1: null, elem2: "acid_cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"hail_cloud": { elem1: null, elem2: "acid_cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"thunder_cloud": { elem1: null, elem2: "acid_cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"pyrocumulus": { elem1: null, elem2: "acid_cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"fire_cloud": { elem1: null, elem2: "acid_cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"ash": { elem1:"hydrogen", elem2:null, chance:0.05 },
"limestone": { elem1:"hydrogen", elem2:null, chance:0.05 },
"quicklime": { elem1:"hydrogen", elem2:null, chance:0.05 },
"slaked_lime": { elem1:"hydrogen", elem2:null, chance:0.05 },
"borax": { elem1:"hydrogen", elem2:null, chance:0.05 },
"ammonia": { elem1:"hydrogen", elem2:null, chance:0.05 },
"bleach": { elem1:"hydrogen", elem2:null, chance:0.05 }
},
category: "gases",
temp: 120,
tempHigh: 400,
stateHigh: "fire",
tempLow: 30,
stateLow: "acid",
burn: 30,
burnTime: 1,
state: "gas",
density: 1.29
},
"glue": {
color: "#f0f0f0",
behavior: behaviors.STICKY,
reactions: {
"clay_shard": {elem1:null, elem2:"baked_clay"},
"porcelain_shard": {elem1:null, elem2:"porcelain"},
"glass_shard": {elem1:null, elem2:"glass"},
"rad_shard": {elem1:null, elem2:"rad_glass"},
"confetti": {elem1:null, elem2:"paper"},
"gold_coin": {elem1:null, elem2:"gold"},
"fly": {elem2:"dead_bug"},
"firefly": {elem2:"dead_bug"},
"ant": {elem2:"dead_bug"},
"rat": {elem2:"rotten_meat", chance:0.05},
},
tempHigh: 475,
stateHigh: ["cyanide_gas","dioxin"],
category: "liquids",
state: "liquid",
density: 1300,
ignore: ["sawdust","particleboard","ice","rime","dry_ice","oxygen_ice","hydrogen_ice","nitrogen_ice"]
},
"soda": {
color: "#422016",
behavior: [
"XX|CR:foam%2|XX",
"M2|XX|M2",
"M2|M1|M2",
],
tempHigh: 100,
stateHigh: ["steam","carbon_dioxide","sugar"],
tempLow: -1.11,
category: "liquids",
reactions: {
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
"rock": { elem2: "wet_sand", chance: 0.0004 },
"water": { elem1: "sugar_water", elem2: "sugar_water" },
"salt": { elem2:"foam", chance:0.05 },
"salt_water": { elem2:"foam", chance:0.01 },
"sugar": { elem2:"foam", chance:0.001 },
"egg": { elem2:"yolk", chance:0.001 },
"candy": { elem2:"foam", chance:0.01 },
"caramel": { elem2:"foam", chance:0.01 },
"rust": { elem2:"iron", chance:0.01 },
"oxidized_copper": { elem2:"copper", chance:0.01 },
},
state: "liquid",
density: 1030,
isFood: true
},
"gray_goo": {
color: "#c0c0c0",
behavior: [
"XX|CH:gray_goo%25|XX",
"M2%5 AND CH:gray_goo%25|DL%5|M2%5 AND CH:gray_goo%25",
"XX|CH:gray_goo%25 AND M1|XX",
],
behaviorOn: [
"XX|XX|XX",
"XX|DL%10|XX",
"M1|M2|M1",
],
reactions: {
"antibody": { elem1:"malware", elem2:null }
},
ignore: ["fire","smoke","malware","flash","light","laser"],
category: "special",
state: "solid",
density: 21450,
excludeRandom: true,
conduct: 0.25,
darkText: true
},
"malware": {
color: ["#8c4ac7","#a13d6a"],
behavior: [
"CL%1|CL%1 AND SH|CL%1",
"CL%1 AND SH|SH%5 AND DL%10|CL%1 AND SH",
"M1%15 AND CL%1|M1%50 AND CL%2 AND SH|M1%15 AND CL%1",
],
reactions: {
"gray_goo": { elem2:"malware" },
"fireball": { elem2:"rocket" },
"wire": { elem2:null, chance:0.01 },
"cloner": { elem2:["ecloner","slow_cloner"], chance:0.01, func:(pixel,cloner) => { cloner.clone = "malware" } },
"ecloner": { elem2:["cloner","slow_cloner"], chance:0.01, func:(pixel,cloner) => { cloner.clone = "malware" } },
"slow_cloner": { elem2:["cloner","ecloner"], chance:0.01, func:(pixel,cloner) => { cloner.clone = "malware" } },
"loopy": { func:(pixel,cloner) => { cloner.clone = "malware" } },
"pipe": { func:(pixel,pipe) => {
// change pipe.stage into 2, 3, or 4
pipe.stage = Math.floor(Math.random()*3)+2;
// change color to "#003600", "#360000", or "#000036"
pipe.color = ["#003600","#360000","#000036"][pipe.stage-2];
} },
"pipe_wall": { elem2:"rock", chance:0.01 },
"lattice": { elem1:"lattice", elem2:null },
"light_bulb": { elem2:"explosion", chance:0.01 },
"battery": { elem2:"explosion", chance:0.01 },
"heater": { elem2:["cooler","superheater"], chance:0.01 },
"cooler": { elem2:["heater","freezer"], chance:0.01 },
"superheater": { elem2:["heater","freezer"], chance:0.01 },
"freezer": { elem2:["cooler","superheater"], chance:0.01 },
"led_r": { elem2:["led_g","led_b"], chance:0.01 },
"led_g": { elem2:["led_r","led_b"], chance:0.01 },
"led_b": { elem2:["led_r","led_g"], chance:0.01 },
"ewall": { elem2:"wall", chance:0.01 },
"border": { elem2:null, chance:0.01 },
"virus": { func: function(pixel1,pixel2){pixel2.heal=false;pixel2.origElem="malware"} },
},
category: "special",
state: "solid",
density: 2.1
},
"ecloner": {
name: "e-cloner",
color: "#dddd00",
behavior: behaviors.WALL,
behaviorOn: behaviors.CLONER,
tick: function(pixel) {
if (pixel.clone) { return }
for (var i = 0; i < adjacentCoords.length; i++) {
var coords = adjacentCoords[i];
var x = pixel.x + coords[0];
var y = pixel.y + coords[1];
if (!isEmpty(x,y,true)) {
pixel.temp = pixelMap[x][y].temp;
if (pixelMap[x][y].clone) { pixel.clone = pixelMap[x][y].clone; break }
var element = pixelMap[x][y].element;
if (element === pixel.element || elements[pixel.element].ignore.indexOf(element) !== -1) { continue }
pixel.clone = element;
break;
}
}
},
ignore: ["cloner","slow_cloner","clone_powder","floating_cloner","wire","ewall","wire","sensor","battery"],
category:"machines",
insulate:true,
darkText: true,
conduct: 1,
hardness: 1,
movable: false
},
"slow_cloner": {
color: "#888800",
behavior: [
"XX|CF%10|XX",
"CF%10|XX|CF%10",
"XX|CF%10|XX",
],
ignore: ["cloner","ecloner","clone_powder","floating_cloner","wall","ewall"],
category:"machines",
insulate:true,
hardness: 1
},
"clone_powder": {
color: "#f0f000",
behavior: [
"XX|CF|XX",
"CF|XX|CF",
"M2|CF AND M1|M2",
],
ignore: ["cloner","ecloner","slow_cloner","floating_cloner","wall","ewall"],
category:"machines",
insulate:true,
state:"solid",
density:2710,
hardness: 1,
darkText: true,
},
"floating_cloner": {
color: "#c7c787",
behavior: [
"XX|CF%3 AND M1%10|XX",
"CF%3 AND M1%10|XX|CF%3 AND M1%10",
"XX|CF%3 AND M1%10|XX",
],
ignore: ["cloner","ecloner","slow_cloner","clone_powder","wall","ewall"],
category:"machines",
insulate:true,
state:"solid",
density:1355,
hardness: 1,
darkText: true,
},
"virus": {
color: "#cc00ff",
tick: function(pixel) {
for (var i = 0; i < adjacentCoords.length; i++) {
var coords = adjacentCoords[i];
var x = pixel.x + coords[0];
var y = pixel.y + coords[1];
if (!isEmpty(x,y,true)) {
var newPixel = pixelMap[x][y]
if (elements[newPixel.element].id !== elements.virus.id && elements[newPixel.element].hardness !== 1 && !pixel.heal && elements.virus.ignore.indexOf(newPixel.element) === -1) {
if (Math.random() < 0.25) { newPixel.origElem = newPixel.element; changePixel(newPixel,"virus"); }
}
else if (elements[newPixel.element].id === elements.virus.id && pixel.heal) { newPixel.heal = true }
}
}
if (pixel.heal && Math.random() < 0.01) {
if (pixel.origElem) { changePixel(pixel,pixel.origElem); delete pixel.heal; delete pixel.origElem }
else { deletePixel(pixel.x,pixel.y); return }
}
tryMove(pixel,pixel.x,pixel.y+1);
doDefaults(pixel)
},
reactions: {
"chlorine": { elem1:null },
"liquid_chlorine": { elem1:null },
"light": { elem1:null, chance:0.1 },
},
ignore: ["fire","smoke","soap","plague","cancer","plasma","light","loopy"],
category: "special",
state: "solid",
density: 600,
excludeRandom: true
},
"ice_nine": {
color: ["#b0dcf7","#bbe9fc","#cefcfc"],
behavior: [
"XX|XX|XX",
"XX|CH:ice%0.5|XX",
"M2|M1|M2",
],
reactions: {
"water": { elem2: "ice_nine" },
"salt_water": { elem2: "ice_nine" },
"dirty_water": { elem2: "ice_nine" },
"sugar_water": { elem2: "ice_nine" },
"seltzer": { elem2: "ice_nine" },
"pool_water": { elem2: "ice_nine" },
"steam": { elem2: "ice_nine" },
"rain_cloud": { elem2: "ice_nine" },
"cloud": { elem2: "ice_nine" },
"snow_cloud": { elem2: "ice_nine" },
"hail_cloud": { elem2: "ice_nine" },
"thunder_cloud": { elem2: "ice_nine" },
"snow": { elem2: "ice_nine" },
"smog": { elem2: "ice_nine" },
"rad_steam": { elem2: "ice_nine" }
},
temp:-100,
category: "special",
state: "solid",
density: 917,
excludeRandom: true
},
"strange_matter": {
color: ["#a4c730","#b6ff57","#74e846","#2ba31d"],
// behavior: [
// "M1%10|M1%10 AND SW%5|M1%10",
// "M1%10 AND CH:strange_matter|XX|M1%10 AND CH:strange_matter",
// "M1|M1 AND SW%5|M1"
// ],
tick: function(pixel) {
if (Math.random() < 0.05 && !isEmpty(pixel.x,pixel.y+1,true)) {
if (elements.strange_matter.ignore.indexOf(pixelMap[pixel.x][pixel.y+1].element) === -1) {
swapPixels(pixel,pixelMap[pixel.x][pixel.y+1]);
}
}
if (Math.random() < 0.05 && !isEmpty(pixel.x,pixel.y-1,true)) {
if (elements.strange_matter.ignore.indexOf(pixelMap[pixel.x][pixel.y-1].element) === -1) {
swapPixels(pixel,pixelMap[pixel.x][pixel.y-1]);
}
}
if (!isEmpty(pixel.x-1,pixel.y,true)) {
if (elements.strange_matter.ignore.indexOf(pixelMap[pixel.x-1][pixel.y].element) === -1) {
changePixel(pixelMap[pixel.x-1][pixel.y],"strange_matter");
}
}
if (!isEmpty(pixel.x+1,pixel.y,true)) {
if (elements.strange_matter.ignore.indexOf(pixelMap[pixel.x+1][pixel.y].element) === -1) {
changePixel(pixelMap[pixel.x+1][pixel.y],"strange_matter");
}
}
var move1Spots = [
[pixel.x, pixel.y+1],
[pixel.x+1, pixel.y+1],
[pixel.x-1, pixel.y+1],
]
if (Math.random() < 0.1) { move1Spots.push([pixel.x-1,pixel.y]) }
if (Math.random() < 0.1) { move1Spots.push([pixel.x+1,pixel.y]) }
if (Math.random() < 0.1) { move1Spots.push([pixel.x,pixel.y-1]) }
if (Math.random() < 0.1) { move1Spots.push([pixel.x-1,pixel.y-1]) }
if (Math.random() < 0.1) { move1Spots.push([pixel.x+1,pixel.y-1]) }
for (var i = 0; i < move1Spots.length; i++) {
var coords = move1Spots[Math.floor(Math.random()*move1Spots.length)];
if (tryMove(pixel, coords[0], coords[1])) { break; }
else { move1Spots.splice(move1Spots.indexOf(coords), 1); }
}
doDefaults(pixel);
},
category: "special",
state: "liquid",
density: 2000,
excludeRandom: true,
ignore: ["fire","smoke","antimatter","strange_matter","wall","ewall","plasma","void","border"],
},
"permafrost": {
color: ["#54443a","#4f4235","#453c30","#524639"],
behavior: behaviors.SUPPORT,
temp: -50,
tempHigh: 10,
stateHigh: "mudstone",
category: "land",
state: "solid",
density: 700
},
"melted_butter": {
color: "#ffe240",
behavior: behaviors.LIQUID,
reactions: {
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
"toast": { color2:["#A84B1E","#C96619","#F9B042"], tempMin:160, chance:0.05 },
"crumb": { color2:["#A84B1E","#C96619","#F9B042"], tempMin:160, chance:0.05 },
"baked_batter": { color2:["#A84B1E","#C96619","#F9B042"], tempMin:160, chance:0.05 },
"baked_potato": { color2:["#A84B1E","#C96619","#F9B042"], tempMin:160, chance:0.05 },
},
temp: 33,
tempLow: 0,
stateLow: "butter",
tempHigh: 1000,
stateHigh: ["smoke","steam","smoke","steam","smoke","steam","smoke","steam","quicklime","salt"],
category: "states",
viscosity: 42,
hidden: true,
state: "liquid",
density: 911,
isFood: true,
stain: 0.05,
},
"melted_cheese": {
color: "#fcdb53",
behavior: behaviors.LIQUID,
reactions: {
"salt": { elem2:null, chance:0.005},
},
temp: 54,
tempLow: 0,
stateLow: "cheese",
tempHigh: 1000,
stateHigh: ["smoke","steam","alcohol_gas","smoke","steam","alcohol_gas","smoke","steam","alcohol_gas","quicklime","salt"],
category: "states",
viscosity: 112,
hidden: true,
state: "liquid",
density: 400,
isFood: true
},
"mushroom_spore": {
color: ["#d1d1d1","#d4cfa9","#b4d4ae","#b98aba","#805236"],
behavior: [
"XX|M2%1.5|XX",
"XX|L2:mushroom_stalk AND C2:mushroom_gill%20|XX",
"XX|M1|XX",
],
reactions: {
"wood": { elem2:"dirt", chance:0.04 },
"tree_brake": { elem2:"dirt", chance:0.04 },
"plant": { elem2:"dirt", chance:0.07 },
"evergreen": { elem2:"dirt", chance:0.07 },
"root": { elem2:"dirt", chance:0.07 },
"grass": { elem2:"dirt", chance:0.08 },
"grass_seed": { elem2:"dirt", chance:0.08 }
},
category: "life",
tempHigh: 225,
stateHigh: "fire",
burn: 10,
burnTime: 20,
breakInto: [null,null,"dust"],
state: "solid",
density: 123.6,
cooldown: defaultCooldown,
seed: true,
darkText: true
},
"mushroom_stalk": {
color: "#d1d1d1",
behavior: [
"XX|XX|XX",
"XX|XX|XX",
"XX|CH:dirt>hyphae%1 AND M1|XX",
],
reactions: {
"wood": { elem2:"dirt", chance:0.04 },
"tree_brake": { elem2:"dirt", chance:0.04 },
"plant": { elem2:"dirt", chance:0.07 },
"evergreen": { elem2:"dirt", chance:0.07 },
"root": { elem2:"dirt", chance:0.07 },
"grass": { elem2:"dirt", chance:0.08 },
"grass_seed": { elem2:"dirt", chance:0.08 },
"ash": { elem2:"dirt", chance:0.04 },
"water": { elem2:"broth", tempMin:70, color2:["#CC9978","#CD8C6F","#BE785E"] },
"salt_water": { elem2:"broth", tempMin:70, color2:["#CC9978","#CD8C6F","#BE785E"] },
"sugar_water": { elem2:"broth", tempMin:70, color2:["#CC9978","#CD8C6F","#BE785E"] },
"seltzer": { elem2:"broth", tempMin:70, color2:["#CC9978","#CD8C6F","#BE785E"] },
},
category: "life",
hidden: true,
tempHigh: 225,
stateHigh: "fire",
burn: 10,
burnTime: 65,
state: "solid",
density: 90.445,
seed: "mushroom_spore",
breakInto: [null,null,"mycelium"]
},
"mushroom_gill": {
color: "#d4cfa9",
tick: function(pixel) {
if (!pixel.mColor) {
// make it a hsl random hue, 54% saturation, 52% lightness
pixel.mColor = "hsl(" + Math.floor(Math.random()*200+180)%360 + ",54%,52%)";
}
if (isEmpty(pixel.x,pixel.y-1) && Math.random() < 0.1) {
createPixel("mushroom_cap",pixel.x,pixel.y-1);
pixelMap[pixel.x][pixel.y-1].color = pixel.mColor;
}
if (isEmpty(pixel.x-1,pixel.y) && Math.random() < 0.02) {
// create either mushroom_gill or mushroom_cap
if (Math.random() < 0.5) {
createPixel("mushroom_gill",pixel.x-1,pixel.y);
pixelMap[pixel.x-1][pixel.y].mColor = pixel.mColor;
} else {
createPixel("mushroom_cap",pixel.x-1,pixel.y);
pixelMap[pixel.x-1][pixel.y].color = pixel.mColor;
}
}
if (isEmpty(pixel.x+1,pixel.y) && Math.random() < 0.02) {
if (Math.random() < 0.5) {
createPixel("mushroom_gill",pixel.x+1,pixel.y);
pixelMap[pixel.x+1][pixel.y].mColor = pixel.mColor;
} else {
createPixel("mushroom_cap",pixel.x+1,pixel.y);
pixelMap[pixel.x+1][pixel.y].color = pixel.mColor;
}
}
doDefaults(pixel);
},
reactions: {
"water": { elem2:"broth", tempMin:70, color2:["#CC9978","#CD8C6F","#BE785E"] },
"salt_water": { elem2:"broth", tempMin:70, color2:["#CC9978","#CD8C6F","#BE785E"] },
"sugar_water": { elem2:"broth", tempMin:70, color2:["#CC9978","#CD8C6F","#BE785E"] },
"seltzer": { elem2:"broth", tempMin:70, color2:["#CC9978","#CD8C6F","#BE785E"] },
},
category: "life",
hidden: true,
movable: false,
tempHigh: 225,
stateHigh: "fire",
burn: 10,
burnTime: 65,
burnInto: "mushroom_spore",
state: "solid",
density: 90.445,
seed: "mushroom_spore",
breakInto: [null,"mycelium","mushroom_spore","poison"]
},
"mushroom_cap": {
color: ["#c76243","#c74442","#c7437e","#c043c7","#7c43c7","#4543c7","#4368c7","#43c7c7"],
singleColor: true,
behavior: behaviors.WALL,
reactions: {
"water": { elem2:"broth", tempMin:70, color2:["#CC9978","#CD8C6F","#BE785E"] },
"salt_water": { elem2:"broth", tempMin:70, color2:["#CC9978","#CD8C6F","#BE785E"] },
"sugar_water": { elem2:"broth", tempMin:70, color2:["#CC9978","#CD8C6F","#BE785E"] },
"seltzer": { elem2:"broth", tempMin:70, color2:["#CC9978","#CD8C6F","#BE785E"] },
},
category: "life",
hidden: true,
tempHigh: 225,
stateHigh: "fire",
burn: 10,
burnTime: 65,
burnInto: "mushroom_spore",
state: "solid",
density: 90.445,
seed: "mushroom_spore",
breakInto: [null,null,"mycelium"]
},
"hyphae": {
color: "#c79789",
behavior: [
"CH:dirt>hyphae,hyphae,mycelium%0.5|CR:mushroom_spore%0.5|CH:dirt>hyphae,hyphae,mycelium%0.5",
"CH:dirt>mycelium%0.5|XX|CH:dirt>mycelium%0.5",
"CH:dirt>hyphae,hyphae,mycelium%0.5|XX|CH:dirt>hyphae,hyphae,mycelium%0.5",
],
reactions: {
"wood": { elem2:"dirt", chance:0.04 },
"tree_brake": { elem2:"dirt", chance:0.04 },
"plant": { elem2:"dirt", chance:0.07 },
"evergreen": { elem2:"dirt", chance:0.07 },
"root": { elem2:"dirt", chance:0.07 },
"grass": { elem2:"dirt", chance:0.08 },
"grass_seed": { elem2:"dirt", chance:0.08 },
"ash": { elem2:"dirt", chance:0.04 },
"water": { elem2:"broth", tempMin:70, color2:["#CC9978","#CD8C6F","#BE785E"] },
"salt_water": { elem2:"broth", tempMin:70, color2:["#CC9978","#CD8C6F","#BE785E"] },
"sugar_water": { elem2:"broth", tempMin:70, color2:["#CC9978","#CD8C6F","#BE785E"] },
"seltzer": { elem2:"broth", tempMin:70, color2:["#CC9978","#CD8C6F","#BE785E"] },
},
category: "life",
hidden: true,
tempHigh: 225,
stateHigh: "fire",
burn: 30,
burnTime: 20,
state: "solid",
density: 462,
seed: "mushroom_spore",
conduct: 0.1,
breakInto: ["dirt","dirt","mycelium"]
},
"mycelium": {
color: ["#734d5e","#734d5e","#734d5e","#61404f","#6b4b5a","#755061","#866372","#987886","#ab8e9a","#bea4ad","#d0b9c1","#e3cfd5"],
behavior: behaviors.POWDER,
tempHigh:225,
stateHigh: "dirt",
tempLow: -50,
stateLow: "permafrost",
burn: 20,
burnTime: 40,
burnInto: "dirt",
category:"land",
state: "solid",
density: 462,
seed: "mushroom_spore"
},
"mulch": {
color: ["#94432c","#7a2912","#571a09"],
behavior: behaviors.POWDER,
tempHigh: 400,
stateHigh: ["dirt","dirt","ash","fire"],
burn: 1,
burnTime: 200,
burnInto: ["dirt","dirt","ash","fire"],
category:"land",
state: "solid",
density: 380
},
"ant_wall": {
color: ["#91643f","#8a593b"],
behavior: behaviors.WALL,
reactions: {
"water": { elem1:["mud","mud","wet_sand"], elem2:null, chance:0.005 },
"dirty_water": { elem1:["mud","mud","wet_sand"], elem2:null, chance:0.006 },
"salt_water": { elem1:["mud","mud","wet_sand"], elem2:null, chance:0.007 },
"sugar_water": { elem1:["mud","mud","wet_sand"], elem2:null, chance:0.003 },
"seltzer": { elem1:["mud","mud","wet_sand"], elem2:null, chance:0.01 },
"pool_water": { elem1:["mud","mud","wet_sand"], elem2:null, chance:0.05 },
"fire": { elem1:["dirt","sand"], chance:0.005 },
},
tempHigh:1400,
stateHigh: ["molten_dirt","molten_glass"],
tempLow: -50,
stateLow: "permafrost",
category:"land",
state: "solid",
breakInto: ["dirt","sand"],
density: 1220,
hidden: true
},
"lichen": {
color: ["#b6d6c3","#769482"],
tick: function(pixel) {
if (!tryMove(pixel,pixel.x,pixel.y+1)) {
var coords = [
[pixel.x+1,pixel.y],
[pixel.x-1,pixel.y],
[pixel.x+1,pixel.y+1],
[pixel.x-1,pixel.y+1],
];
for (var i = 0; i < coords.length; i++) {
if (Math.random() < 0.005 && isEmpty(coords[i][0],coords[i][1])) {
if (!isEmpty(coords[i][0],coords[i][1]+1) && (outOfBounds(coords[i][0],coords[i][1]+1) || pixelMap[coords[i][0]][coords[i][1]+1].element!=="lichen") ) {
createPixel(pixel.element,coords[i][0],coords[i][1]);
}
}
}
}
doDefaults(pixel);
},
reactions: {
"carbon_dioxide": { elem2:"oxygen", chance:0.05 },
"rock": { elem2:"dirt", chance:0.0025 },
"rock_wall": { elem2:"dirt", chance:0.0025 },
"gravel": { elem2:"dirt", chance:0.0025 },
"vinegar": { elem1:null, chance:0.01 }
},
tempHigh: 400,
stateHigh: "fire",
burn: 50,
burnTime: 20,
breakInto: "dust",
category: "life",
state: "solid",
density: 1.5
},
"antimatter": {
color: "#a89ba8",
behavior: [
"M2|DB%50 AND M2 AND EX:8>fire,positron|M2",
"M1|XX|M1",
"M1|DB%50 AND M1 AND EX:8>fire,positron|M1",
],
ignore: ["antimatter_bomb"],
category: "special",
state: "gas",
density: 2.1,
excludeRandom: true
},
"plastic": {
color: "#c5dede",
behavior: behaviors.WALL,
tempHigh: 250,
burn: 10,
burnTime: 200,
burnInto: ["dioxin","smoke","dioxin","smoke","stench"],
category: "solids",
state: "solid",
density: 1052
},
"molten_plastic": {
color: "#a4b3b3",
behavior: behaviors.LIQUID,
viscosity: 20
},
"cellulose": {
color: "#c7d4c9",
behavior: behaviors.LIQUID,
reactions: {
"herb": {elem1:"incense", elem2:null}
},
tempHigh: 100,
stateHigh: "paper",
tempLow: 0,
stateLow: "paper",
burn: 1,
burnTime: 300,
burnInto: ["smoke","smoke","smoke","steam"],
category: "life",
state: "liquid",
density: 1500,
viscosity: 2500,
hidden: true
},
"wax": {
color: "#fff3d6",
behavior: behaviors.STURDYPOWDER,
tempHigh: 57,
stateHigh: "melted_wax",
category: "powders",
state: "solid",
density: 900
},
"melted_wax": {
color: "#d4c196",
behavior: behaviors.LIQUID,
temp: 67,
tempLow: 57,
stateLow: "wax",
tempHigh: 1000,
stateHigh: ["smoke","fire","carbon_dioxide","hydrogen"],
category: "liquids",
hidden: true,
state: "liquid",
density: 900,
viscosity: 1.355
},
"incense": {
color: "#361f19",
behavior: behaviors.STURDYPOWDER,
tempHigh: 2320,
stateHigh: ["fragrance","smoke"],
burn: 10,
burnTime: 500,
burnInto: ["fragrance","smoke"],
fireElement: ["fragrance","smoke","smoke"],
breakInto: "sawdust",
category: "powders",
state: "solid",
density: 686
},
"fuse": {
color: "#825d38",
behavior: behaviors.WALL,
tempHigh: 500,
stateHigh: "fire",
burn: 100,
burnTime: 1,
fireElement: "smoke",
burnInto: "pop",
category: "solids",
state: "solid",
density: 1000
},
"dioxin": {
color: "#b8b8b8",
behavior: behaviors.GAS,
reactions: {
"cell": { elem2:"cancer", chance:0.0015 },
"blood": { elem2:"infection", chance:0.01 },
"antibody": { elem2:"blood", chance:0.025 },
"frog": { elem2:"meat", chance:0.05 },
"fish": { elem2:"meat", chance:0.05 },
"rat": { elem2:"rotten_meat", chance:0.05 },
"bird": { elem2:"rotten_meat", chance:0.05 },
"plant": { elem2:"dead_plant", chance:0.05 },
"vine": { elem2:"dead_plant", chance:0.05 },
"cactus": { elem2:"dead_plant", chance:0.05 },
"sapling": { elem2:"dead_plant", chance:0.05 },
"grass": { elem2:"dead_plant", chance:0.05 },
"head": { func:behaviors.KILLPIXEL2, chance:0.005 },
"ash": { elem1:null, chance:0.05 },
"dirt": { elem1:null, chance:0.05 },
"mud": { elem1:null, chance:0.05 },
"sand": { elem1:null, chance:0.05 },
"wet_sand": { elem1:null, chance:0.05 },
"clay_soil": { elem1:null, chance:0.05 },
},
category: "gases",
state: "gas",
density: 1.977
},
"insulation": {
color: "#b8aea5",
behavior: behaviors.WALL,
category: "solids",
insulate: true,
state: "solid",
noMix: true
},
"sponge": {
color: ["#bf9c00","#ad8e05","#876f05"],
properties: {
"damp":0
},
tick: function(pixel) {
var coordsToCheck = [
[pixel.x-1,pixel.y],
[pixel.x+1,pixel.y],
[pixel.x,pixel.y-1],
[pixel.x,pixel.y+1],
];
for (var i = 0; i < coordsToCheck.length; i++) {
var coord = coordsToCheck[i];
if (!isEmpty(coord[0],coord[1],true)) {
var newPixel = pixelMap[coord[0]][coord[1]];
if (elements[newPixel.element].state === "liquid" && ((elements[newPixel.element].density || 0) < 2500)) {
deletePixel(coord[0],coord[1]);
}
}
}
doBurning(pixel);
doHeat(pixel);
},
reactions: {
"soap": { elem2:"bubble" }
},
category: "solids",
burn: 5,
burnTime: 300,
tempHigh: 500,
stateHigh: "fire",
state: "solid",
density: 65,
movable: false,
},
"bamboo": {
color: ["#7cc00c","#77a012"],
behavior: behaviors.WALL,
tempHigh: 380,
stateHigh: ["ember","fire","fire","fire"],
burn: 10,
burnTime: 200,
burnInto: ["ember","fire","fire","fire"],
category: "solids",
state: "solid",
density: 686,
breakInto: "sawdust",
seed: "bamboo_plant"
},
"iron": {
color: ["#cbcdcd","#bdbdbd"],
behavior: behaviors.WALL,
reactions: {
"water": { elem1:"rust", chance:0.0025 },
"salt_water": { elem1:"rust", chance:0.005 },
"dirty_water": { elem1:"rust", chance:0.04 },
"pool_water": { elem1:"rust", chance:0.04 },
"sugar_water": { elem1:"rust", chance:0.0035 },
"seltzer": { elem1:"rust", chance:0.006 },
"salt": { elem1:"rust", chance:0.004 },
"blood": { elem1:"rust", chance:0.003 },
"infection": { elem1:"rust", chance:0.003 },
"antibody": { elem1:"rust", chance:0.003 },
"fire": { elem1:"rust", chance:0.0025 },
},
tempHigh: 1538,
category: "solids",
density: 7860,
conduct: 0.47,
hardness: 0.4,
darkText: true
},
"copper": {
color: ["#a95232","#be4322","#c76035"],
behavior: behaviors.WALL,
reactions: {
"blood": { elem1:"oxidized_copper", chance:0.003 },
"infection": { elem1:"oxidized_copper", chance:0.003 },
"antibody": { elem1:"oxidized_copper", chance:0.003 },
"fire": { elem1:"oxidized_copper", chance:0.0025 },
},
category: "solids",
tempHigh: 1085,
density: 8960,
conduct: 0.95,
hardness: 0.3,
fireColor: ["#07BA4F","#00BC5B","#00C2A9","#11B7E7","#C6F2EC"]
},
"gold": {
color: ["#fff0b5","#986a1a","#f0bb62"],
behavior: behaviors.WALL,
tempHigh: 1064,
category: "solids",
density: 19300,
conduct: 0.81,
hardness: 0.25,
breakInto: "gold_coin"
},
"steel": {
color: "#71797e",
behavior: behaviors.WALL,
reactions: {
"water": { elem1:"rust", chance:0.002 },
"salt_water": { elem1:"rust", chance:0.004 },
"dirty_water": { elem1:"rust", chance:0.03 },
"pool_water": { elem1:"rust", chance:0.03 },
"sugar_water": { elem1:"rust", chance:0.003 },
"seltzer": { elem1:"rust", chance:0.005 },
"salt": { elem1:"rust", chance:0.003 },
"blood": { elem1:"rust", chance:0.002 },
"infection": { elem1:"rust", chance:0.002 },
"antibody": { elem1:"rust", chance:0.002 },
},
tempHigh: 1455.5,
category: "solids",
density: 7850,
conduct: 0.42,
hardness: 0.8
},
"nickel": {
color: "#727472",
behavior: behaviors.WALL,
tempHigh: 1455,
category: "solids",
density: 8900,
conduct: 0.51,
hardness: 0.4
},
"zinc": {
color: ["#8d8c8e","#f6f6f1","#c7c7c5","#ccccca","#6b6a6a","#848382"],
behavior: behaviors.WALL,
tempHigh: 419.53,
category: "solids",
density: 7068,
conduct: 0.53,
hardness: 0.25,
fireColor: ["#91B797","#CAE4CA","#F1F2F0"]
},
"silver": {
color: "#cacaca",
behavior: behaviors.WALL,
tempHigh: 961.8,
category: "solids",
density: 10497,
conduct: 0.99,
hardness: 0.25
},
"tin": {
color: ["#9e9d98","#aeada4"],
tick: function(pixel) {
if (pixel.temp < 13.2 && Math.random() < 0.0005) {
changePixel(pixel,"metal_scrap");
}
doDefaults(pixel)
},
tempHigh: 231.9,
category: "solids",
density: 7260,
conduct: 0.45,
hardness: 0.15,
movable: false
},
"lead": {
color: ["#6c6c6a","#838381"],
behavior: behaviors.WALL,
tempHigh: 327.5,
category: "solids",
density: 11343,
conduct: 0.41,
hardness: 0.15,
fireColor: ["#DBD1E9","#D7E9F2","#9AB0D1"]
},
"aluminum": {
color: ["#d1c6be","#b5c0ad","#b9b8bc"],
reactions: {
"radiation": { elem2:"electric", temp1:200 }
},
behavior: behaviors.WALL,
tempHigh: 660.3,
category: "solids",
density: 2710,
conduct: 0.73,
hardness: 0.05,
breakInto: "metal_scrap",
fireColor: "#A7B3BF"
},
"tungsten": {
color: ["#d4d3cd","#c3c0b8","#bcbaae","#625950"],
behavior: behaviors.WALL,
tempHigh: 3422,
category: "solids",
density: 19300,
conduct: 0.65,
hardness: 0.75
},
"molten_tungsten": {
color: ['#ffff67', '#ffd367', '#ff9e00', '#d1ff5c', '#5cffb0', '#0073ff', '#ca57ff', '#ffba57', '#ff8c00', '#c46f28', '#c45928', '#c44300']
},
"brass": {
color: ["#cb9e5d","#865e39"],
behavior: behaviors.WALL,
reactions: {
"ammonia": { elem1:"metal_scrap", color1:["#cb9e5d","#865e39"], chance:0.01 }
},
tempHigh: 927,
category: "solids",
density: 8550,
conduct: 0.52,
hardness: 0.275,
hidden: true
},
"bronze": {
color: "#cd7f32",
behavior: behaviors.WALL,
reactions: {
"water": { elem1:"oxidized_copper", chance:0.00125 },
"salt_water": { elem1:"oxidized_copper", chance:0.0025 },
"dirty_water": { elem1:"oxidized_copper", chance:0.02 },
"pool_water": { elem1:"oxidized_copper", chance:0.02 },
"sugar_water": { elem1:"oxidized_copper", chance:0.00175 },
"seltzer": { elem1:"oxidized_copper", chance:0.003 },
"blood": { elem1:"oxidized_copper", chance:0.0015 },
"infection": { elem1:"oxidized_copper", chance:0.0015 },
"antibody": { elem1:"oxidized_copper", chance:0.0015 },
},
tempHigh: 913,
category: "solids",
density: 8150,
conduct: 0.44,
hardness: 0.225,
hidden: true
},
"sterling": {
color: ["#858478","#eae8e2","#bfbcb7"],
behavior: behaviors.WALL,
tempHigh: 802,
category: "solids",
density: 10375.25,
conduct: 0.95,
hardness: 0.275,
hidden: true
},
"gallium": {
color: ["#b3b3b3","#cccccc","#dbdbdb"],
behavior: behaviors.WALL,
tempHigh: 29.76,
category: "solids",
density: 5100,
conduct: 0.05,
hardness: 0.15,
},
"molten_gallium": {
color: ["#f7f7f7","#d9d7d7"],
behavior: behaviors.LIQUID,
tempHigh: 2400,
tempLow: 29.76,
density: 6095,
stateLow: "gallium",
reactions: {
"aluminum": { elem1:"alga", elem2:"alga", chance:0.01 },
"molten_aluminum": { elem1:"alga", elem2:"molten_alga", chance:0.05 },
"sodium": { elem1:"hydrogen", elem2:"salt", chance:0.005 },
"steel": { elem2:"iron", chance:0.005 },
"gold": { elem1:null, elem2:"blue_gold", chance:0.01 },
},
stain: 0.05,
},
"gallium_gas": {
density: 6.31
},
"rose_gold": {
color: ["#f58f8f","#d06c6c","#f58f8f"],
behavior: behaviors.WALL,
tempHigh: 897,
category: "solids",
density: 12900,
conduct: 0.87,
hardness: 0.275,
breakInto: "gold_coin",
breakIntoColor: ["#f58f8f","#d06c6c","#f58f8f"],
hidden: true
},
"purple_gold": {
color: ["#f58fda","#d06cb5","#f58fda"],
behavior: behaviors.WALL,
tempHigh: 1060,
category: "solids",
density: 11005,
conduct: 0.87,
hardness: 0.15,
breakInto: "gold_coin",
breakIntoColor: ["#f58fda","#d06cb5","#f58fda"],
hidden: true
},
"blue_gold": {
color: ["#94c2c7","#7ba3b2","#94c2c7"],
behavior: behaviors.WALL,
tempHigh: 491,
category: "solids",
density: 12900,
conduct: 0.87,
hardness: 0.275,
breakInto: "gold_coin",
breakIntoColor: ["#94c2c7","#7ba3b2","#94c2c7"],
hidden: true
},
"electrum": {
color: ["#c5c794","#b0b27b","#c5c794"],
behavior: behaviors.WALL,
tempHigh: 1063.9,
category: "solids",
density: 13750,
conduct: 0.9,
hardness: 0.25,
breakInto: "gold_coin",
breakIntoColor: ["#c5c794","#b0b27b","#c5c794"],
hidden: true,
alias: "green gold"
},
"pyrite": {
color: ["#e8e0cb","#cdcaaf","#726a53","#8f835e","#bfb9a0",],
behavior: behaviors.WALL,
tempHigh: 1182.5,
category: "solids",
density: 4900,
state: "solid",
conduct: 0.5,
hardness: 0.6,
hidden: true,
alias: "fool's gold"
},
"solder": {
color: "#a1a19d",
behavior: behaviors.WALL,
tempHigh: 200,
category: "solids",
density: 8885,
conduct: 0.43,
hardness: 0.15,
hidden: true
},
"amber": {
temp: 20,
tempHigh: 345,
stateHigh: "smoke",
breakInto: [null,null,"sap"],
category: "solids"
},
"molten_copper": {
reactions: {
"molten_zinc": { elem1: null, elem2: "molten_brass" },
"molten_tin": { elem1: null, elem2: "molten_bronze" },
"molten_silver": { elem1: null, elem2: "molten_sterling" },
"molten_gold": { elem1: null, elem2: "molten_rose_gold" },
"molten_sulfur": { elem1: null, elem2: "molten_copper_sulfate" },
"sulfur_gas": { elem1: null, elem2: "molten_copper_sulfate" }
},
density: 8020
},
"molten_gold": {
reactions: {
"molten_silver": { elem1: null, elem2: "molten_electrum" },
"molten_aluminum": { elem1: null, elem2: "molten_purple_gold" },
"molten_gallium": { elem1: null, elem2: "molten_blue_gold" },
"molten_alga": { elem1: "molten_purple_gold", elem2: "molten_blue_gold" },
"gallium_gas": { elem1: null, elem2: "molten_blue_gold" },
},
density: 17310
},
"molten_silver": {
density: 9320
},
"molten_iron": {
reactions: {
"charcoal": { elem1: "molten_steel", elem2: null },
"diamond": { elem1: "molten_steel", elem2: null },
"carbon_dioxide": { elem1: "molten_steel", elem2: null }
},
density: 6980
},
"molten_nickel": {
density: 7810
},
"molten_tin": {
reactions: {
"molten_lead": { elem1: null, elem2: "molten_solder" }
},
density: 6990
},
"molten_lead": {
density: 10660
},
"molten_solder": {
color: ["#94A4B0","#AFBBC9","#CCD6E5","#FFFFFF"],
behavior: behaviors.LIQUID
},
"juice": {
color: "#f0bf3d",
behavior: behaviors.LIQUID,
reactions: {
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
"seltzer": { elem1: "soda", elem2: "foam" },
"carbon_dioxide": { elem1: "soda", elem2: "foam" },
},
tempHigh: 160,
stateHigh: ["steam","sugar"],
tempLow: -10,
stateLowColorMultiplier: 1.1,
category: "liquids",
state: "liquid",
density: 1054,
stain: 0.05,
isFood: true
},
"juice_ice": {
stateHighColorMultiplier: 0.91,
},
"broth": {
color: "#dbb169",
behavior: behaviors.LIQUID,
reactions: {
"petal": { color1:["#CC9978","#CD8C6F","#BE785E","#CC9978","#CD8C6F","#BE785E","#A9D475","#5AF353","#8E5FA5"], tempMin:70, chance:0.01 },
"pistil": { color1:["#CC9978","#CD8C6F","#BE785E","#CC9978","#CD8C6F","#BE785E","#A9D475","#5AF353","#8E5FA5"], tempMin:70, chance:0.01 },
"potato": { color1:"#DFD0CB", tempMin:70, chance:0.05 },
"melted_cheese": { color1:"#dbc469", tempMin:70, chance:0.05 },
"beans": { color1:"#db9769", tempMin:70, chance:0.05 },
"wheat": { color1:"#dbbd8a", tempMin:70, chance:0.05 },
"algae": { color1:"#7dba57", tempMin:70, chance:0.05 },
"tomato": { color1:"#F9A24E", tempMin:70, chance:0.05 },
"sauce": { color1:"#F9A24E", tempMin:70, chance:0.05 },
"ketchup": { color1:"#F9A24E", tempMin:70, chance:0.05 },
"mushroom_stalk": { color1:["#CC9978","#CD8C6F","#BE785E"], tempMin:70, chance:0.05 },
"mushroom_cap": { color1:["#CC9978","#CD8C6F","#BE785E"], tempMin:70, chance:0.05 },
"mushroom_gill": { color1:["#CC9978","#CD8C6F","#BE785E"], tempMin:70, chance:0.05 },
"hyphae": { color1:["#CC9978","#CD8C6F","#BE785E"], tempMin:70, chance:0.05 },
},
tempHigh: 130,
stateHigh: ["steam","steam","steam","fragrance"],
tempLow: 0,
category: "food",
state: "liquid",
density: 1052,
conduct: 0.03,
stain: -0.01,
hidden: true,
isFood: true,
extinguish: true
},
"milk": {
color: "#fafafa",
behavior: behaviors.LIQUID,
onMix: function(milk1, milk2) {
if (shiftDown && Math.random() < 0.01) {
changePixel(milk1,"butter")
}
},
reactions: {
"melted_chocolate": { elem1:"chocolate_milk", elem2:null },
"chocolate": { elem1:"chocolate_milk", elem2:"melted_chocolate", chance:0.05 },
"coffee_ground": { elem1:"chocolate_milk", chance:0.05 },
"juice": { elem1:"fruit_milk", elem2:null, chance:0.05 },
"soda": { elem1:"pilk", elem2:null, chance:0.1 },
"yolk": { elem1:"eggnog", elem2:null, chance:0.1 },
"cell": { elem1:"yogurt", chance:0.1 },
"ash": { elem1:"soap", chance:0.1 },
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
"caramel": { color1:"#C8B39A", elem2:null, chance:0.05 },
"sugar": { elem2:null, chance:0.005},
},
tempLow: 0,
stateLow: "ice_cream",
stateLowColorMultiplier: [0.97,0.93,0.87],
tempHigh: 100,
stateHigh: ["smoke","smoke","smoke","quicklime"],
viscosity: 1.5,
category: "liquids",
state: "liquid",
density: 1036.86,
isFood: true
},
"chocolate_milk": {
color: "#664934",
behavior: behaviors.LIQUID,
reactions: {
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
},
tempLow: 0,
stateLow: "ice_cream",
stateLowColorMultiplier: [0.97,0.93,0.87],
tempHigh: 93,
stateHigh: "yogurt",
stateHighColorMultiplier: 1.1,
viscosity: 1.5,
category: "liquids",
state: "liquid",
density: 1181,
hidden: true,
isFood: true
},
"fruit_milk": {
color: "#c9988f",
behavior: behaviors.LIQUID,
reactions: {
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
},
tempLow: 0,
stateLow: "ice_cream",
stateLowColorMultiplier: [0.97,0.93,0.87],
tempHigh: 93,
stateHigh: "yogurt",
stateHighColorMultiplier: 1.1,
viscosity: 1.5,
category: "liquids",
state: "liquid",
density: 1045,
hidden: true,
isFood: true
},
"pilk": {
color: "#e9cba3",
behavior: behaviors.LIQUID,
reactions: {
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
},
tempLow: 0,
stateLow: "ice_cream",
stateLowColorMultiplier: [0.97,0.93,0.87],
tempHigh: 93,
stateHigh: "yogurt",
stateHighColorMultiplier: 1.1,
viscosity: 1.25,
category: "liquids",
state: "liquid",
density: 1033,
hidden: true,
isFood: true
},
"eggnog": {
color: "#ddbf98",
behavior: behaviors.LIQUID,
reactions: {
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
},
tempLow: 0,
stateLow: "ice_cream",
stateLowColorMultiplier: [0.97,0.93,0.87],
tempHigh: 93,
stateHigh: "yogurt",
stateHighColorMultiplier: 1.1,
viscosity: 1.5,
category: "liquids",
state: "liquid",
density: 1033,
hidden: true,
isFood: true
},
"egg": {
color: "#e0d3ab",
tick: function(pixel) {
if (pixel.start === pixelTicks) {return}
if (!tryMove(pixel, pixel.x, pixel.y+1)) {
if (pixel.animal || pixel.fall < 20) {
if (Math.random() < 0.5) {
if (!tryMove(pixel, pixel.x+1, pixel.y+1)) {
tryMove(pixel, pixel.x-1, pixel.y+1);
}
} else {
if (!tryMove(pixel, pixel.x-1, pixel.y+1)) {
tryMove(pixel, pixel.x+1, pixel.y+1);
}
}
pixel.fall = 0;
}
else if (outOfBounds(pixel.x,pixel.y+1) || (!isEmpty(pixel.x,pixel.y+1,true) && elements.egg.ignore.indexOf(pixelMap[pixel.x][pixel.y+1].element) === -1 && elements[pixelMap[pixel.x][pixel.y+1].element].state === "solid")) {
changePixel(pixel,"yolk")
}
else {pixel.fall = 0}
if (pixel.animal && pixelTicks-pixel.start >= 500 && Math.random() < 0.2) {
changePixel(pixel,pixel.animal)
}
}
else {pixel.fall ++}
if (pixel.temp < -2 || pixel.temp > 100) {
pixel.animal = null;
}
doDefaults(pixel);
},
ignore: ["paper","sponge","straw","wheat","rat","frog","pollen","clay","snow","mud","wet_sand","tinder","feather","bread","ice_cream","dough"],
innerColor: "#ffffff",
properties: { "fall":0 },
tempHigh: 1500,
stateHigh: ["steam","calcium","carbon_dioxide","sulfur_gas"],
breakInto: "yolk",
category: "food",
state: "solid",
density: 1031,
cooldown: defaultCooldown
},
"yolk": {
color: ["#ffbe33","#ffcf33"],
behavior: behaviors.LIQUID,
reactions: {
"dna": { elem1:"homunculus", elem2:null, chance:0.05 }
},
tempHigh: 100,
stateHigh: "hard_yolk",
tempLow: 0,
stateLow: "hard_yolk",
category: "food",
state: "liquid",
density: 1027.5,
viscosity: 270,
isFood: true
},
"hard_yolk": {
color: "#dead43",
behavior: behaviors.STURDYPOWDER,
tempHigh: 400,
stateHigh: "smoke",
category: "food",
hidden: true,
isFood: true,
state: "solid",
density: 1031
},
"cream": {
color: "#f7f7f7",
behavior: behaviors.LIQUID,
onMix: function(milk1, milk2) {
if ((shiftDown && Math.random() < 0.01) || (elements[milk2.element].id === elements.milk.id && Math.random() < 0.00025)) {
changePixel(milk1,"butter")
}
},
reactions: {
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
"melted_chocolate": { color1:"#664934", elem2:null },
"chocolate": { color1:"#664934", elem2:"melted_chocolate", chance:0.05 },
"juice": { elem1:"fruit_milk", elem2:null, chance:0.05 },
"soda": { elem1:"pilk", elem2:null, chance:0.1 },
"yolk": { elem1:"#eggnog", elem2:null, chance:0.1 },
"caramel": { color1:"#C8B39A", chance:0.05 },
"sugar": { elem2:null, chance:0.005},
},
viscosity: 1.5,
tempHigh: 1000,
stateHigh: ["smoke","smoke","smoke","steam","steam","calcium"],
tempLow: 0,
stateLow: "ice_cream",
stateLowColorMultiplier: 0.97,
category: "liquids",
hidden: true,
isFood: true,
state: "liquid",
density: 959.97,
},
"nut_milk": {
color: "#D7D1C3",
behavior: behaviors.LIQUID,
viscosity: 1.5,
tempHigh: 100,
stateHigh: "steam",
tempLow: 0,
stateLow: "ice",
category: "liquids",
state: "liquid",
density: 1107.41,
conduct: 0.005,
stain: -0.1,
desc: "Dairy-free!",
isFood: true,
hidden: true
},
"dough": {
color: "#bfac91",
behavior: behaviors.STURDYPOWDER,
onMix: function(dough,ingredient) {
if (elements[ingredient.element].isFood && elements[ingredient.element].id !== elements.dough.id && elements[ingredient.element].id !== elements.flour.id && elements[ingredient.element].id !== elements.batter.id && elements[ingredient.element].id !== elements.bread.id) {
var rgb1 = dough.color.match(/\d+/g);
var rgb2 = ingredient.color.match(/\d+/g);
// average the colors
var rgb = [
Math.round((parseInt(rgb1[0])*10+parseInt(rgb2[0]))/11),
Math.round((parseInt(rgb1[1])*10+parseInt(rgb2[1]))/11),
Math.round((parseInt(rgb1[2])*10+parseInt(rgb2[2]))/11)
];
// convert rgb to hex
var hex = RGBToHex(rgb);
dough.color = pixelColorPick(dough, hex);
}
},
reactions: {
"milk": { elem2:"broth", color2:"#ECC891", tempMin:70 },
"cream": { elem2:"broth", color2:"#ECC891", tempMin:70 },
"yeast": { elem2:"dough", tempMin:40, chance:0.01 },
"cream": { elem2:"dough", tempMin:40, chance:0.01 },
"baking_soda": { elem2:"dough", tempMin:40, chance:0.01 },
"quicklime": { elem2:"dough", tempMin:40, chance:0.01 },
},
category: "food",
tempHigh: 94,
stateHigh: "bread",
//stateHighColorMultiplier: 0.9,
burn:40,
burnTime:25,
burnInto:"ash",
state: "solid",
density: 526.9,
isFood: true
},
"batter": {
color: "#d4bc85",
behavior: behaviors.LIQUID,
onMix: function(batter,ingredient) {
if (elements[ingredient.element].isFood && elements[ingredient.element].id !== elements.batter.id && elements[ingredient.element].id !== elements.flour.id && elements[ingredient.element].id !== elements.yolk.id && elements[ingredient.element].id !== elements.dough.id && elements[ingredient.element].id !== elements.baked_batter.id) {
var rgb1 = batter.color.match(/\d+/g);
var rgb2 = ingredient.color.match(/\d+/g);
// average the colors
var rgb = [
Math.round((parseInt(rgb1[0])*10+parseInt(rgb2[0]))/11),
Math.round((parseInt(rgb1[1])*10+parseInt(rgb2[1]))/11),
Math.round((parseInt(rgb1[2])*10+parseInt(rgb2[2]))/11)
];
// convert rgb to hex
var hex = RGBToHex(rgb);
batter.color = pixelColorPick(batter, hex);
if ((elements[ingredient.element].density > elements.batter.density || shiftDown) && Math.random() < 0.05) {
// 50% change to delete ingredient
if (Math.random() < 0.5) { deletePixel(ingredient.x, ingredient.y); }
else {
ingredient.color = pixelColorPick(ingredient, hex);
}
}
}
},
reactions: {
"yeast": { elem2:"batter", tempMin:40, chance:0.01 },
"cream": { elem2:"batter", tempMin:40, chance:0.01 },
"baking_soda": { elem2:"batter", tempMin:40, chance:0.01 },
"quicklime": { elem2:"batter", tempMin:40, chance:0.01 },
},
category: "food",
tempHigh: 94,
stateHigh: "baked_batter",
stateHighColorMultiplier: 0.9,
burn:40,
burnTime:25,
burnInto:"ash",
state: "liquid",
viscosity: 10000,
density: 1001,
hidden: true,
isFood: true
},
"homunculus": {
color: ["#c4b270","#9c916a","#9e8955","#a89a76"],
behavior: [
"XX|XX|XX",
"M2%0.5|XX|M2%0.5",
"XX|M1|XX",
],
reactions: {
"milk": { elem2:null, chance:0.025 },
"blood": { elem2:null, chance:0.05 },
"sugar": { elem2:null, chance:0.025 },
"meat": { elem2:null, chance:0.001 },
"cooked_meat": { elem2:null, chance:0.0005 },
"oxygen": { elem2:"carbon_dioxide" },
"radiation": { elem1:["human","skin"], elem2:null }
},
tempHigh: 100,
stateHigh: "meat",
tempLow: 0,
stateLow: "frozen_meat",
category: "life",
state: "solid",
density: 1450,
hidden: true,
breakInto: ["blood","slime"]
},
"butter": {
color: "#ffe46b",
behavior: behaviors.STURDYPOWDER,
tempHigh: 33,
stateHigh: "melted_butter",
category: "food",
state: "solid",
density: 860,
isFood: true
},
"cheese": {
color: "#fcba03",
behavior: behaviors.STURDYPOWDER,
reactions: {
"dirty_water": { elem1:"rotten_cheese", chance:0.1 },
"stench": { elem1:"rotten_cheese", chance:0.2 },
"fly": { elem1:"rotten_cheese", chance:0.2 },
"dioxin": { elem1:"rotten_cheese", elem2:null, chance:0.1 },
"uranium": { elem1:"rotten_cheese", chance:0.1 },
"cancer": { elem1:"rotten_cheese", chance:0.1 },
"plague": { elem1:"rotten_cheese", elem2:null, chance:0.3 },
"ant": { elem1:"rotten_cheese", chance:0.1 },
"worm": { elem1:"rotten_cheese", chance:0.1 },
"rat": { elem1:"rotten_cheese", chance:0.1 },
"mushroom_spore": { elem1:"rotten_cheese", chance:0.1 },
"mushroom_stalk": { elem1:"rotten_cheese", chance:0.1 },
"mercury": { elem1:"rotten_cheese", elem2:null, chance:0.2 },
"mercury_gas": { elem1:"rotten_cheese", elem2:null, chance:0.1 },
"virus": { elem1:"rotten_cheese", chance:0.1 },
"poison": { elem1:"rotten_cheese", elem2:null, chance:0.5 },
"infection": { elem1:"rotten_cheese", elem2:null, chance:0.1 },
"ink": { elem1:"rotten_cheese", elem2:null, chance:0.1 },
"acid": { elem1:"rotten_cheese", elem2:null, chance:0.5 },
"acid_gas": { elem1:"rotten_cheese", chance:0.4 },
"cyanide": { elem1:"rotten_cheese", elem2:null, chance:0.5 },
"cyanide_gas": { elem1:"rotten_cheese", elem2:null, chance:0.5 },
"rotten_meat": { elem1:"rotten_cheese", chance:0.02 },
},
tempHigh: 54,
stateHigh: "melted_cheese",
category: "food",
state: "solid",
density: 477.62,
isFood: true
},
"rotten_cheese": {
color: ["#ffcc40","#c1b338","#839930"],
behavior: [
"XX|CR:plague,stench,stench,stench,fly%0.25 AND CH:cheese>rotten_cheese%1|XX",
"CH:cheese>rotten_cheese%1|XX|CH:cheese>rotten_cheese%1",
"XX|M1 AND CH:cheese>rotten_cheese%1|XX",
],
tempHigh: 54,
stateHigh: ["melted_cheese","melted_cheese","melted_cheese","melted_cheese","melted_cheese","melted_cheese","melted_cheese","melted_cheese","melted_cheese","stench"],
category: "food",
state: "solid",
density: 470,
isFood: true,
hidden: true
},
"chocolate": {
color: "#4d2818",
behavior: behaviors.STURDYPOWDER,
tempHigh: 31,
stateHigh: "melted_chocolate",
category: "food",
state: "solid",
density: 1325,
isFood: true
},
"grape": {
color: ["#b84b65","#a10e69","#a10e95","#8a3eab"],
behavior: [
"XX|ST:vine|XX",
"ST:vine|XX|ST:vine",
"M2|M1|M2",
],
reactions: {
"radiation": { elem1:"explosion", chance:0.1, color1:"#291824" },
"rock": { elem1:"juice", chance:0.1, color1:"#291824" },
"concrete": { elem1:"juice", chance:0.1, color1:"#291824" },
"basalt": { elem1:"juice", chance:0.1, color1:"#291824" },
"limestone": { elem1:"juice", chance:0.1, color1:"#291824" },
"tuff": { elem1:"juice", chance:0.1, color1:"#291824" },
"water": { elem2:"juice", chance:0.005, color2:"#291824" },
"sugar_water": { elem2:"juice", chance:0.025, color2:"#291824" },
"acid": { elem1:"juice", color1:"#291824" },
"acid_gas": { elem1:"juice", color1:"#291824" },
},
innerColor: "#cc7492",
tempHigh: 256,
stateHigh: ["steam","sugar"],
category: "food",
state: "solid",
density: 1154,
breakInto: "juice",
breakIntoColor: "#291824",
ignoreAir: true,
isFood: true
},
"vinegar": {
color: "#ffecb3",
behavior: behaviors.LIQUID,
reactions: {
"milk": { elem1: null, elem2: "cheese" },
"pilk": { elem1: null, elem2: "cheese", color2:"#c48a25" },
"fruit_milk": { elem1: null, elem2: "cheese", color2:"#c2864e" },
"chocolate_milk": { elem1: null, elem2: "cheese", color2:"#6b4000" },
"eggnog": { elem1: null, elem2: "cheese", color2:"#ffdb63" },
"nut_milk": { elem1: null, elem2: "cheese", color2:"#ded0ad" },
"yogurt": { elem1: null, elem2: "cheese" },
"baking_soda": { elem1: "sodium_acetate", elem2: "carbon_dioxide", attr1:{"foam":20} },
"limestone": { elem1: "sodium_acetate", elem2: "carbon_dioxide", attr1:{"foam":5} },
"rust": { elem2:"iron", chance:0.05 },
"oxidized_copper": { elem2:"copper", chance:0.05 },
"egg": { elem2:"yolk", chance:0.0005 },
"yolk": { elem1:"mayo", elem2:"mayo", chance:0.1 },
"mushroom_spore": { elem2:null, chance:0.05 },
"mushroom_gill": { elem2:null, chance:0.05 },
"mushroom_cap": { elem2:null, chance:0.05 },
"pollen": { elem2:null, chance:0.05 },
"salt": { elem1: null, elem2: "sodium_acetate", chance:0.05 },
"lettuce": { elem2:"pickle", chance:0.01 },
"egg": { elem2:"pickle", color2:"#e0e0ab", chance:0.01 },
"tomato": { elem2:"pickle", color2:"#fa6e11", chance:0.01 },
"grape": { elem2:"pickle", color2:"#b86a4b", chance:0.01 },
"pumpkin": { elem2:"pickle", color2:"#ffa42e", chance:0.01 },
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
},
viscosity: 12,
tempHigh: 100.6,
stateHigh: ["steam","carbon_dioxide","methane"],
tempLow: -2.22,
stateLowName: "frozen_vinegar",
category: "liquids",
state: "liquid",
density: 1006,
stain: -0.8,
isFood: true
},
"herb": {
color: ["#2e5a09","#3c6a16","#507b28","#759d3c"],
reactions: {
"water": { elem2:"tea", tempMin:80 },
"salt_water": { elem2:"tea", tempMin:80 },
"sugar_water": { elem2:"tea", tempMin:80 },
"seltzer": { elem2:"tea", tempMin:80 },
"stench": { elem2:null, chance:0.25 },
"steam": { elem2:"fragrance", chance:0.1 },
"flea": { elem2:null, chance:0.01 },
"termite": { elem2:null, chance:0.01 },
"fly": { elem2:null, chance:0.01 },
"ant": { elem2:null, chance:0.01 },
"stink_bug": { elem2:null, chance:0.01 },
},
behavior: behaviors.POWDER,
tempHigh: 300,
stateHigh: ["fire","smoke","smoke","smoke","ash"],
tempLow: -2,
stateLow: "frozen_plant",
burn:10,
burnTime:300,
burnInto: ["fire","smoke","smoke","smoke","smoke","smoke","smoke","fragrance"],
category:"food",
state: "solid",
density: 1400,
isFood: true,
},
"lettuce": {
color: ["#a2c96b","#81C520","#639917"],
behavior: behaviors.POWDER,
tempHigh: 300,
stateHigh: ["fire","smoke","smoke","steam","ash"],
burn:5,
burnTime:500,
burnInto: ["fire","smoke","smoke","steam","ash"],
category:"food",
state: "solid",
density: 1400,
isFood: true
},
"pickle": {
color: ["#afc520","#999517"],
behavior: behaviors.STURDYPOWDER,
tempHigh: 300,
stateHigh: ["fire","smoke","smoke","steam","ash","carbon_dioxide","alcohol_gas"],
burn:1,
burnTime:500,
burnInto: ["fire","smoke","smoke","steam","ash","carbon_dioxide","alcohol_gas"],
breakInto: "juice",
breakIntoColor: "#CF9F08",
category:"food",
state: "solid",
density: 625,
isFood: true
},
"tomato": {
color: ["#FA4611","#FF5615","#FF7833"],
behavior: [
"XX|ST:vine|XX",
"ST:vine|XX|ST:vine",
"XX|M1|XX",
],
reactions: {
"rock": { elem1:"sauce", chance:0.1 },
"concrete": { elem1:"sauce", chance:0.1 },
"basalt": { elem1:"sauce", chance:0.1 },
"limestone": { elem1:"sauce", chance:0.1 },
"tuff": { elem1:"sauce", chance:0.1 },
},
tempHigh: 300,
stateHigh: ["fire","smoke","smoke","steam","ash"],
burn:1,
burnTime:500,
burnInto: ["fire","smoke","smoke","steam","ash"],
breakInto: "sauce",
category:"food",
state: "solid",
density: 1014.42,
isFood: true
},
"sauce": {
color: ["#bf1600","#bf2300","#bf3600"],
behavior: behaviors.LIQUID,
reactions: {
"sugar": { elem1:"ketchup", elem2:null, chance:0.1 },
"sugar_water": { elem1:"ketchup", elem2:"water", chance:0.1 },
"vinegar": { elem1:"ketchup", elem2:null, chance:0.1 },
"stench": { elem2:null },
"salt": { elem2:null, chance:0.005},
},
viscosity: 2600,
tempHigh: 260,
stateHigh: ["steam","salt"],
tempLow: -2,
category:"food",
state: "liquid",
density: 1031.33,
stain: 0.01,
isFood: true
},
"pumpkin": {
color: ["#ff822e","#ff8c2e"],
tick: function(pixel) {
if (pixel.grow && Math.random() < 0.01) {
if (isEmpty(pixel.x,pixel.y-1)) { createPixel("wood",pixel.x,pixel.y-1) }
if (isEmpty(pixel.x,pixel.y+1)) { createPixel("pumpkin",pixel.x,pixel.y+1) }
if (isEmpty(pixel.x+pixel.grow,pixel.y+1)) { createPixel("pumpkin",pixel.x+pixel.grow,pixel.y+1) }
if (isEmpty(pixel.x+pixel.grow,pixel.y)) { createPixel("pumpkin",pixel.x+pixel.grow,pixel.y) }
pixel.grow = 0;
}
doDefaults(pixel);
},
category: "food",
tempHigh: 800,
stateHigh: "ash",
state: "solid",
density: 490.3,
seed: "pumpkin_seed",
breakInto: [null,null,null,null,null,"pumpkin_seed"],
isFood: true,
movable: false
},
"pumpkin_seed": {
color: ["#FFE9CA","#ffdcc2","#ffcaab"],
tick: function(pixel) {
if (!tryMove(pixel,pixel.x,pixel.y+1) && Math.random() < 0.01) {
if (!pixel.stage) {
if (!isEmpty(pixel.x,pixel.y+1,true)) {
var soil = pixelMap[pixel.x][pixel.y+1];
if (eLists.SOIL.indexOf(soil.element) !== -1) {
if (tryMove(pixel,pixel.x,pixel.y-1,"vine")) {
pixelMap[pixel.x][pixel.y+1].stop = true;
pixel.stage = 1;
}
}
}
}
else if (pixel.stage == 1) {
if (isEmpty(pixel.x,pixel.y-1)) {
createPixel("plant",pixel.x,pixel.y-1);
}
pixel.stage = 2;
}
else if (pixel.stage == 2) {
var dir = Math.random() < 0.5 ? -1 : 1;
if (!isEmpty(pixel.x+dir,pixel.y)) { dir = -dir; }
if (isEmpty(pixel.x+dir,pixel.y)) {
createPixel("pumpkin",pixel.x+dir,pixel.y);
pixelMap[pixel.x+dir][pixel.y].grow = dir;
}
changePixel(pixel,"vine");
pixel.stop = true;
}
}
doDefaults(pixel);
},
tempHigh: 400,
stateHigh: "fire",
tempLow: -2,
stateLow: "frozen_plant",
burn: 50,
burnTime: 20,
category: "life",
state: "solid",
density: 950.33,
hidden: true,
cooldown: defaultCooldown,
seed: true,
isFood: true
},
"corn": {
color: ["#f8d223","#d6ba2a","#f7f5ba","#dbd281","#cdb12d"],
tick: function(pixel) {
if (pixel.temp >= 180) {
changePixel(pixel,"popcorn");
if (isEmpty(pixel.x,pixel.y-1)) {
tryMove(pixel,pixel.x,pixel.y-1);
if (isEmpty(pixel.x-1,pixel.y)) { createPixel("pop",pixel.x-1,pixel.y) }
if (isEmpty(pixel.x+1,pixel.y)) { createPixel("pop",pixel.x+1,pixel.y) }
if (isEmpty(pixel.x,pixel.y-1)) { createPixel("pop",pixel.x,pixel.y-1) }
if (isEmpty(pixel.x,pixel.y+1)) { createPixel("pop",pixel.x,pixel.y+1) }
}
}
doDefaults(pixel)
},
category: "food",
burn: 10,
burnTime: 200,
breakInto: "flour",
breakIntoColor: ["#ffe9a8","#ffecb3","#ffe28a"],
state: "solid",
density: 721,
seed: "corn_seed",
isFood: true,
movable: false,
},
"popcorn": {
color: ["#a6a076","#ebe4ab","#ebe4ab","#ebe4ab","#ebe4ab","#ebe4ab","#ebe4ab","#c99947"],
behavior: behaviors.POWDER,
category: "food",
tempHigh: 500,
stateHigh: "ash",
burn: 20,
burnTime: 200,
burnInto: ["fire","ash"],
state: "solid",
density: 360.5,
hidden: true,
isFood: true
},
"corn_seed": {
color: ["#f2b813","#f9e3ba"],
behavior: [
"XX|M2%0.25|XX",
"XX|L2:plant,corn AND C2:corn%30|XX",
"XX|M1|XX",
],
tempHigh: 400,
stateHigh: "fire",
tempLow: -2,
stateLow: "frozen_plant",
burn: 50,
burnTime: 20,
breakInto: null,
category: "life",
state: "solid",
density: 721,
hidden: true,
cooldown: defaultCooldown,
seed: true
},
"potato": {
color: ["#d99857","#d98757","#a66933"],
behavior: [
"XX|SH:wire%1|XX",
"SH:wire%1|XX|SH:wire%1",
"M2|M1 AND SH:wire%1|M2",
],
reactions: {
"zinc": { charge2:1, chance:0.01 },
"copper": { charge2:1, chance:0.01 },
},
innerColor: "#e3c688",
breakInto: "mashed_potato",
tempHigh: 176,
stateHigh: "baked_potato",
burn: 10,
burnTime: 300,
burnInto: "ash",
category: "food",
state: "solid",
density: 675,
seed: "potato_seed",
isFood: true
},
"baked_potato": {
color: ["#F5B72F","#E89F0C","#9f7501"],
behavior: behaviors.STURDYPOWDER,
tempHigh: 400,
stateHigh: "ash",
burn: 20,
burnTime: 300,
burnInto: "ash",
breakInto: "crumb",
breakIntoColor: ["#f6be46","#F5B72F","#f5b324","#f4aa0b","#f3ab1b","#E89F0C","#d08f0b","#b87e0a","#b28201","#9f7501"],
category: "food",
state: "solid",
density: 675,
isFood: true,
hidden: true
},
"mashed_potato": {
color: ["#F7F6E4","#F0ECD4","#E4D38B"],
behavior: behaviors.STURDYPOWDER,
tempHigh: 400,
stateHigh: ["ash","steam",null,null,null],
burn: 3,
burnTime: 300,
burnInto: ["ash","steam","smoke","smoke","smoke"],
category: "food",
state: "solid",
density: 675,
isFood: true,
hidden: true
},
"potato_seed": {
color: ["#cda57f","#aa7437","#bc9563"],
behavior: [
"XX|CH:dirt>fiber|XX",
"CH:dirt>potato%5|CH:potato%1|CH:dirt>potato%5",
"XX|SW:dirt%3 AND M1|XX",
],
tempHigh: 400,
stateHigh: "fire",
tempLow: -2,
stateLow: "frozen_plant",
burn: 50,
burnTime: 20,
breakInto: null,
category: "life",
state: "solid",
density: 675,
hidden: true,
cooldown: defaultCooldown,
seed: true
},
"root": {
color: "#80715b",
behavior: [
"XX|XX|XX",
"XX|XX|XX",
"CH:dirt,mud,sand,wet_sand,clay_soil,clay,mycelium,grass,color_sand>root,fiber%0.5|CH:dirt,mud,sand,wet_sand,clay_soil,clay,mycelium,grass,color_sand>root,fiber,fiber%0.5|CH:dirt,mud,sand,wet_sand,clay_soil,clay,mycelium,grass,color_sand>root,fiber%0.5",
],
reactions: {
"rock": { elem2:"sand", chance:0.0004 },
"mud": { elem2:"dirt", chance:0.005 },
"wet_sand": { elem2:"sand", chance:0.005 },
"water": { elem2:null, chance:0.005 },
"sugar_water": { elem2:null, chance:0.008 }
},
tempHigh: 275,
stateHigh: "dirt",
tempLow: -50,
stateLow: "fiber",
burn: 20,
burnTime: 60,
burnInto: "dirt",
breakInto: "sawdust",
category: "life",
state: "solid",
density: 1250,
conduct: 0.1,
hidden: true
},
"fiber": {
color: ["#6b563e","#5c553e","#42342d"],
behavior: behaviors.STURDYPOWDER,
tempHigh:275,
stateHigh: "dirt",
tempLow: -50,
stateLow: "permafrost",
burn: 20,
burnTime: 60,
burnInto: "dirt",
category:"life",
hidden: true,
breakInto: "tinder",
state: "solid",
density: 462
},
"yeast": {
color: ["#ad9166","#9a7f4e","#d8bb8d"],
behavior: [
"XX|CL:70%10|XX",
"CL:70%10 AND SW:bread%30|XX|CL:70%10 AND SW:bread%30",
"XX|M1|XX",
],
reactions: {
"bread": { elem1:"bread" },
"potato": { elem2:"alcohol", chance:0.005, color2:"#fec400" },
"mashed_potato": { elem2:"alcohol", chance:0.005, color2:"#fec400" },
"grape": { elem2:"alcohol", chance:0.005, color2:"#916851" },
"juice": { elem2:"alcohol", chance:0.015, color2:"#916851" },
"sugar": { elem2:"alcohol", chance:0.005, color2:"#80724d" },
"sugar_water": { elem2:"alcohol", chance:0.005, color2:"#80724d" },
"soda": { elem2:"alcohol", chance:0.005, color2:"#80724d" },
"corn": { elem2:"alcohol", chance:0.005, color2:"#b8b6a2" },
"honey": { elem2:"alcohol", chance:0.005, color2:"#dccb72" },
"molasses": { elem2:"alcohol", chance:0.005, color2:"#803924" },
"herb": { elem2:"tea", chance:0.005 },
"milk": { elem2:"cheese", chance:0.005 },
"oxygen": { elem2:"carbon_dioxide", chance:0.05 },
"algae": { elem1:"lichen", elem2:"lichen", chance:0.02 },
"bleach": { elem1:null, elem2: "foam", attr2:{"foam":40}, chance:0.02, temp2:75 },
},
tempHigh: 110,
stateHigh: "bread",
burn: 50,
burnTime: 20,
burnInto: ["smoke","smoke","smoke","ash"],
category: "food",
state: "solid",
density: 1180,
isFood: true
},
"bread": {
color: "#debd8c",
behavior: behaviors.STURDYPOWDER,
reactions: {
"honey": { elem1:"gingerbread", elem2:null },
"molasses": { elem1:"gingerbread", elem2:null },
"sap": { elem1:"gingerbread", elem2:null },
"caramel": { elem1:"gingerbread", elem2:null },
},
tempHigh: 176,
stateHigh: "toast",
category: "food",
burn: 30,
burnTime: 200,
burnInto: ["smoke","smoke","smoke","ash"],
breakInto: "crumb",
state: "solid",
density: 233.96,
isFood: true
},
"toast": {
color: "#c08655",
behavior: behaviors.STURDYPOWDER,
tempHigh: 550,
stateHigh: "ash",
category: "food",
burn: 50,
burnTime: 170,
burnInto: ["smoke","smoke","smoke","ash"],
breakInto: "crumb",
breakIntoColor: ["#c8946a","#c08655","#ba7a45","#a86d3e"],
state: "solid",
density: 233.96,
isFood: true
},
"gingerbread": {
color: ["#a66530","#bf773d","#cc7d41"],
behavior: behaviors.SUPPORT,
tempHigh: 875,
stateHigh: "ash",
category: "food",
burn: 30,
burnTime: 200,
burnInto: ["smoke","smoke","smoke","ash"],
breakInto: "crumb",
breakIntoColor: ["#ba7136","#a66530","#8a5428","#774822","#c7844d","#bf773d","#ab6a36","#975e30","#d28c56","#cc7d41","#c97636","#b56a30"],
state: "solid",
density: 233.96,
isFood: true
},
"crumb": {
color: ["#e2c69c","#debd8c","#d7b075","#d2a665"],
behavior: behaviors.POWDER,
tempHigh: 550,
stateHigh: "ash",
category: "food",
burn: 15,
burnTime: 200,
burnInto: ["smoke","smoke","smoke","ash"],
state: "solid",
density: 233.96,
isFood: true,
hidden: true
},
"baked_batter": {
color: "#fcdf7e",
behavior: behaviors.STURDYPOWDER,
tempHigh: 550,
stateHigh: "ash",
category: "food",
burn: 10,
burnTime: 400,
burnInto: ["smoke","smoke","smoke","ash"],
breakInto: "crumb",
state: "solid",
density: 233.96,
hidden: true,
isFood: true
},
"wheat": {
color: ["#f1b569","#edb864","#de9c45","#c2853d"],
behavior: behaviors.WALL,
reactions: {
"rock": { elem1:"flour", elem2:"rock" },
"water": { elem2:"tea", tempMin:80, color2:"#9e4c00" },
"salt_water": { elem2:"tea", tempMin:80, color2:"#9e4c00" },
"sugar_water": { elem2:"tea", tempMin:80, color2:"#9e4c00" },
"seltzer": { elem2:"tea", tempMin:80, color2:"#9e4c00" },
},
tempHigh: 100,
stateHigh: "straw",
tempLow: -2,
stateLow: "straw",
burn: 25,
burnTime: 200,
category:"food",
breakInto: "flour",
state: "solid",
density: 769,
seed: "wheat_seed",
isFood: true
},
"candy": {
color: "#e6cab1",
behavior: behaviors.WALL,
tempHigh: 186,
stateHigh: "caramel",
breakInto: "sugar",
hardness: 0.15,
category: "food",
state: "solid",
density: 900,
isFood: true
},
"coffee_bean": {
color: ["#994528","#772C12","#5c2513","#4a2416"],
behavior: behaviors.POWDER,
reactions: {
"water": { elem2:"coffee", tempMin:80 },
"salt_water": { elem2:"coffee", tempMin:80 },
"sugar_water": { elem2:"melted_chocolate", tempMin:65 },
"seltzer": { elem2:"coffee", tempMin:80 },
"stench": { elem2:null },
"oxygen": { elem2:"fragrance", chance:0.01 },
},
tempHigh: 400,
stateHigh: "fire",
breakInto: ["coffee_ground",null],
burn: 10,
burnInto: ["fire","smoke","smoke","smoke","smoke","smoke","smoke","fragrance"],
category: "food",
state: "solid",
density: 650,
isFood: true
},
"coffee_ground": {
color: ["#26130C","#422213"],
behavior: behaviors.POWDER,
reactions: {
"water": { elem1:"coffee", elem2:"coffee", tempMin:70 },
"salt_water": { elem1:"coffee", elem2:"coffee", tempMin:70 },
"sugar_water": { elem1:"melted_chocolate", elem2:"melted_chocolate", tempMin:60 },
"seltzer": { elem1:"coffee", elem2:"coffee", tempMin:70 },
"coffee": { elem1:"coffee", tempMin:70 },
"melted_chocolate": { elem1:"melted_chocolate", tempMin:60 },
"stench": { elem2:null },
"oxygen": { elem2:"fragrance", chance:0.01 },
"flea": { elem2:null, chance:0.01 },
},
tempHigh: 400,
stateHigh: "fire",
burn: 25,
burnInto: ["fire","smoke","smoke","smoke","smoke","smoke","smoke","fragrance"],
category: "food",
state: "solid",
density: 1002,
isFood: true,
hidden: true
},
"nut": {
color: ["#d69965","#c98c57","#b57a47","#8f6038"],
behavior: behaviors.POWDER,
reactions: {
"water": { elem2:"nut_milk", chance:0.00025 },
"salt_water": { elem2:"nut_milk", chance:0.00025 },
"sugar_water": { elem2:"nut_milk", chance:0.00025 },
"seltzer": { elem2:"nut_milk", chance:0.00025 },
"rock": { elem1:"nut_oil", chance:0.02, tempMin:60 },
"concrete": { elem1:"nut_oil", chance:0.02, tempMin:60 },
"basalt": { elem1:"nut_oil", chance:0.02, tempMin:60 },
"limestone": { elem1:"nut_oil", chance:0.01, tempMin:60 },
},
tempHigh: 400,
stateHigh: "fire",
burn: 25,
burnInto: ["fire","smoke","ash"],
breakInto: ["nut_meat",null],
category: "food",
state: "solid",
density: 325,
isFood: true,
},
"nut_oil": {
color: "#E7D784",
behavior: behaviors.LIQUID,
reactions: {
"toast": { color2:["#A84B1E","#C96619","#F9B042"], tempMin:160, chance:0.05 },
"crumb": { color2:["#A84B1E","#C96619","#F9B042"], tempMin:160, chance:0.05 },
"baked_batter": { color2:["#A84B1E","#C96619","#F9B042"], tempMin:160, chance:0.05 },
"baked_potato": { color2:["#A84B1E","#C96619","#F9B042"], tempMin:160, chance:0.05 },
"steam": { elem1:"explosion", tempMin:150, chance:0.1 },
},
viscosity: 38,
tempHigh: 250,
stateHigh: ["fire","smoke","smoke","smoke"],
category:"food",
state: "liquid",
density: 910,
isFood: true
},
"nut_meat": {
color: ["#deba8e","#d1a56f","#ba8b50"],
behavior: behaviors.POWDER,
tick: function(pixel) {
if (Math.random() < 0.005 && !isEmpty(pixel.x,pixel.y-1,true) && eLists.SOIL.indexOf(pixelMap[pixel.x][pixel.y-1].element) !== -1) {
var nutX = Math.random() < 0.5 ? 1 : -1;
if (!isEmpty(pixel.x+nutX,pixel.y,true) && eLists.SOIL.indexOf(pixelMap[pixel.x+nutX][pixel.y].element) !== -1) {
changePixel(pixelMap[pixel.x+nutX][pixel.y],"nut")
}
deletePixel(pixel.x,pixel.y-1);
tryMove(pixel,pixel.x,pixel.y-1,"fiber");
}
},
reactions: {
"water": { elem2:"nut_milk", chance:0.0005 },
"salt_water": { elem2:"nut_milk", chance:0.0005 },
"sugar_water": { elem2:"nut_milk", chance:0.0005 },
"seltzer": { elem2:"nut_milk", chance:0.0005 },
},
tempHigh: 150,
stateHigh: ["nut_butter","nut_butter","nut_butter","nut_butter","nut_butter","nut_oil"],
burn: 20,
burnInto: ["fire","smoke"],
category: "food",
state: "solid",
density: 905,
isFood: true,
hidden: true,
},
"nut_butter": {
color: "#cd9141",
behavior: behaviors.LIQUID,
reactions: {
"salt": { elem2:null, chance:0.005},
"water": { elem1:"nut_milk", elem2:"nut_milk", chance:0.05 },
"salt_water": { elem1:"nut_milk", elem2:"nut_milk", chance:0.05 },
"sugar_water": { elem1:"nut_milk", elem2:"nut_milk", chance:0.05 },
"seltzer": { elem1:"nut_milk", elem2:"nut_milk", chance:0.05 },
},
viscosity: 200000,
tempHigh: 232,
stateHigh: ["smoke","smoke","smoke","smoke","salt"],
category: "food",
state: "liquid",
density: 1090.5,
isFood: true,
hidden: true,
},
"jelly": {
color: "#A35298",
behavior: behaviors.LIQUID,
viscosity: 200000,
tempHigh: 200,
stateHigh: ["smoke","sugar"],
tempLow: -5,
stateLow: ["sugar_ice","sugar_ice","juice_ice"],
category: "food",
state: "liquid",
density: 1245,
isFood: true,
hidden: true,
},
"baking_soda": {
color: "#ededed",
behavior: behaviors.POWDER,
reactions: {
"juice": { elem1:"water", elem2:["carbon_dioxide","foam"] },
"chlorine": { elem1:["carbon_dioxide","seltzer","salt","salt_water","water"] },
"glue": {elem1:"slime", elem2:"slime", chance:0.1},
},
category: "food",
state: "solid",
density: 2200,
tempHigh: 200,
stateHigh: ["salt","carbon_dioxide"],
isFood: true
},
"yogurt": {
color: "#f0efe6",
behavior: [
"XX|XX|XX",
"XX|XX|XX",
"M2%5|M1|M2%5",
],
tempHigh: 1000,
stateHigh: ["smoke","smoke","smoke","calcium"],
tempLow: 0,
stateLowName: "frozen_yogurt",
stateLowColorMultiplier: 1.05,
category: "food",
state: "liquid",
density: 820.33,
isFood: true,
alias: "yoghurt"
},
"frozen_yogurt": {
behavior: behaviors.STURDYPOWDER,
category: "food",
isFood: true,
},
"ice_cream": {
color: ["#f7f7f7","#ededed","#dedede"],
behavior: behaviors.STURDYPOWDER,
temp: 0,
tempHigh: 15,
stateHigh: "cream",
stateHighColorMultiplier: 1.03,
category: "food",
state: "solid",
density: 1096,
isFood: true
},
"beans": {
//color: ["#f33d02","#f04703","#fd9d24","#ffbf61"],
//color: ["#b81901","#b61a00","#e97501","#f9922b"],
color: ["#db1c0b","#db3c0b","#fa8023","#ffa12e"],
behavior: behaviors.LIQUID,
category: "food",
tempHigh: 350,
stateHigh: ["fire","fire","ash"],
burn:3,
burnTime:500,
burnInto: ["fire","smoke","smoke","steam","ash"],
state: "liquid",
density: 721,
viscosity: 1000,
isFood: true
},
"dry_ice": {
color: "#e6e6e6",
behavior: behaviors.WALL,
category: "solids",
temp: -98.5,
tempHigh: -78.5,
stateHigh: "carbon_dioxide",
state: "solid",
density: 1562
},
"nitrogen_ice": {
color: "#e6e6e6",
behavior: behaviors.WALL,
category: "solids",
temp: -259.86,
tempHigh: -209.86,
stateHigh: "liquid_nitrogen",
state: "solid",
density: 1562,
hidden: true
},
"particleboard": {
color: ["#cca77c","#ad8b63","#b59d81","#c7a073","#c9b297"],
behavior: behaviors.WALL,
tempHigh: 500,
stateHigh: ["ash","fire","fire","fire"],
category: "solids",
burn: 2,
burnTime: 400,
burnInto: ["ash","fire"],
state: "solid",
hardness: 0.2,
breakInto: "sawdust",
hidden: true
},
"skin": {
color: ["#f3e7db","#f7ead0","#eadaba","#d7bd96","#a07e56","#825c43","#604134","#3a312a"],
singleColor: true,
tick: function(pixel) {
if (pixel.temp > 40 && Math.random() < 0.005) {
for (var i = 0; i < adjacentCoords.length; i++) {
var coords = adjacentCoords[i];
var x = pixel.x + coords[0];
var y = pixel.y + coords[1];
if (isEmpty(x,y)) {
pixel.temp -= 20;
createPixel("salt_water",x,y)
break;
}
}
}
if (pixel.temp < 36 && Math.random() < 0.1) {
pixel.temp += 1;
}
doDefaults(pixel);
},
reactions: {
"cell": { chance:0.01, func:function(pixel1,pixel2){
changePixel(pixel2,"skin");
pixel2.color = pixelColorPick(pixel2,RGBToHex(pixel1.color.match(/\d+/g)))
if (pixel1.origColor) { pixel2.origColor = pixel1.origColor }
} },
"acid": { elem1:"blood" },
"soap": { elem2:null, chance:0.005 },
"light": { stain1:"#825043" },
"poison": { stain1:"#cc564b" },
"poison_gas": { stain1:"#cc564b" },
"infection": { stain1:"#cc564b" },
"pollen": { stain1:"#cc564b" },
"dust": { stain1:"#cc564b" },
"flea": { stain1:"#cc564b" },
"mushroom_spore": { stain1:"#cc564b" },
"mushroom_stalk": { stain1:"#cc564b" },
"chlorine": { stain1:"#cc564b" },
"quicklime": { stain1:"#cc564b" },
},
category:"solids",
breakInto: [null,null,null,"blood","dust"],
temp: 37,
tempHigh: 200,
stateHigh: ["cooked_meat","cooked_meat","cooked_meat","steam"],
tempLow: -18,
stateLow: "frozen_meat",
burn:5,
burnTime:400,
burnInto:"cooked_meat",
state: "solid",
density: 1019.5,
conduct: 0.05,
movable: false,
},
"hair": {
color: ["#C6C3BF","#EEDFC0","#DAB575","#BF9F6C","#C67945","#9B6E47","#967454","#945F36","#4C3D2E","#5A3E2D","#1c1c1c","#4A2227","#6D342B","#9D4C3B","#C25E3B"],
singleColor: true,
behavior: behaviors.WALL,
category:"solids",
tempHigh: 223,
stateHigh: ["smoke","smoke","smoke","ash","ash","stench"],
burn:15,
burnTime:400,
burnInto:["smoke","smoke","smoke","ash","ash","stench"],
breakInto: [null,null,null,null,"dust"],
state: "solid",
density: 2395,
conduct: 0.05,
hidden: true
},
"alcohol": {
color: "#c9c5b1",
behavior: behaviors.LIQUID,
reactions: {
"virus": { elem2:null },
"plague": { elem2:null },
"charcoal": { color1:"#bdbdbd", chance:0.05 },
},
tempHigh: 78.37,
tempLow: -113.88,
burn: 100,
burnTime: 3,
fireColor: ["#80acf0","#96cdfe","#bee6d4"],
category: "liquids",
state: "liquid",
density: 785.1,
stain: -0.25,
isFood: true,
darkText: true
},
"alcohol_gas": {
density: 1.627
},
"basalt": {
color: ["#2e2e2e","#333333","#3d3d3d"],
behavior: behaviors.STURDYPOWDER,
reactions: {
"fly": { elem2:"dead_bug", chance:0.25, oneway:true },
"firefly": { elem2:"dead_bug", chance:0.2, oneway:true },
"stink_bug": { elem2:"dead_bug", chance:0.15, oneway:true },
"bee": { elem2:"dead_bug", chance:0.1, oneway:true },
"bird": { elem2:"feather", chance:0.025, oneway:true },
"egg": { elem2:"yolk", oneway:true },
"bone": { elem2:"oil", tempMin:300, chance:0.005, oneway:true },
"dead_plant": { elem2:"charcoal", tempMin:200, chance:0.005, oneway:true },
"charcoal": { elem2:"diamond", tempMin:800, tempMax:900, chance:0.005, oneway:true },
},
tempHigh: 1262.5,
stateHigh: "magma",
category: "land",
state: "solid",
density: 3000,
hardness: 0.65,
breakInto: "gravel"
},
"tuff": {
color: ["#927659","#81644B","#685843","#685135","#644F3A"],
behavior: behaviors.SUPPORTPOWDER,
reactions: {
"fly": { elem2:"dead_bug", chance:0.25, oneway:true },
"firefly": { elem2:"dead_bug", chance:0.2, oneway:true },
"stink_bug": { elem2:"dead_bug", chance:0.15, oneway:true },
"bee": { elem2:"dead_bug", chance:0.1, oneway:true },
"bird": { elem2:"feather", chance:0.025, oneway:true },
"egg": { elem2:"yolk", oneway:true },
"bone": { elem2:"oil", tempMin:300, chance:0.005, oneway:true },
"dead_plant": { elem2:"charcoal", tempMin:200, chance:0.005, oneway:true },
"charcoal": { elem2:"diamond", tempMin:800, tempMax:900, chance:0.005, oneway:true },
},
tempHigh: 1080,
stateHigh: "magma",
category: "land",
state: "solid",
density: 2605,
hardness: 0.4,
breakInto: "gravel"
},
"molten_tuff": {
color: ["#ff932c","#ff762c","#ff5800"],
behavior: behaviors.MOLTEN,
temp: 1080,
tempLow: 1000,
stateLow: "tuff",
viscosity: 10000,
category: "states",
state: "liquid",
density: 2725,
hidden: true
},
"soap": {
color: "#f2f2f2",
behavior: [
"XX|CR:bubble%0.25|XX",
"M2|XX|M2",
"M2|M1|M2",
],
reactions: {
"rust": { elem2: "iron", chance:0.01 },
"oxidized_copper": { elem2: "copper", chance:0.01 },
"blood": { elem2:null, chance:0.02 },
"dirty_water": { elem2: "water" },
"salt_water": { elem2: "water" },
"oxygen": { elem2: "bubble" },
"plague": { elem2: null },
"virus": { func: function(pixel1,pixel2){pixel2.heal=true} },
"infection": { elem2: ["blood",null], chance:0.02 },
"mushroom_spore": { elem2: null, chance:0.02 },
"lichen": { elem2: null, chance:0.005 },
"rotten_meat": { elem2: "meat" },
"rotten_cheese": { elem2: "cheese" },
"acid_cloud": { elem2: "rain_cloud" },
"oil": { elem2: null, chance:0.02 },
"soda": { elem2: "sugar_water", chance:0.02 },
"ink": { elem2: null, chance:0.02 },
"dye": { elem2: null, chance:0.02 },
"glue": { elem2: null, chance:0.02 },
"stench": { elem2: null },
"cancer": { elem2: null, chance:0.01 },
"rat": { elem2: null, chance:0.01 },
"ant": { elem2: "dead_bug", chance:0.1 },
"bee": { elem2: "dead_bug", chance:0.1 },
"fly": { elem2: "dead_bug", chance:0.1 },
"firefly": { elem2: "dead_bug", chance:0.1 },
"worm": { elem2: "dead_bug", chance:0.1 },
"flea": { elem2: "dead_bug", chance:0.1 },
"termite": { elem2: "dead_bug", chance:0.1 },
"stink_bug": { elem2: "dead_bug", chance:0.1 },
"smog": { elem2: "cloud" },
"water": { elem1: ["foam","bubble"], chance:0.005 },
"salt_water": { elem1: ["foam","bubble"], chance:0.005 },
"sugar_water": { elem1: ["foam","bubble"], chance:0.005 },
"seltzer": { elem1: ["foam","bubble"], chance:0.005 },
"pool_water": { elem1: ["foam","bubble"], chance:0.005 },
"fire": { elem1: "fragrance" },
},
tempHigh: 100,
stateHigh: "bubble",
viscosity: 500,
state: "liquid",
category:"liquids",
density: 1055,
stain: -1
},
"bleach": {
color: "#ffffff",
behavior: behaviors.LIQUID,
reactions: {
"acid": { elem1: "chlorine", elem2:"poison_gas" },
"acid_gas": { elem1: "chlorine", elem2:"poison_gas" },
"acid_cloud": { elem1: "chlorine", elem2:"poison_gas" },
"water": { elem1:null, elem2:"dirty_water" },
"plague": { elem2: null },
"cell": { elem2: null, chance: 0.05 },
"tadpole": { elem2: null, chance: 0.05 },
"cancer": { elem2: null, chance: 0.01 },
"fish": { elem2: "rotten_meat", chance: 0.01 },
"oil": { elem1:null, elem2: "chlorine", chance: 0.01 },
"lamp_oil": { elem1:null, elem2: "chlorine", chance: 0.01 },
"blood": { elem2: null },
"infection": { elem2: null },
"vinegar": { elem1:"chlorine", elem2:"sodium_acetate" },
"ammonia": { elem1:"poison_gas", elem2:null }, // Mustard Gas
"alcohol": { elem1:"poison_gas", elem2:null }, // Chloroform
"soap": { elem1:"poison_gas", elem2:null, chance:0.1 },
"poison": { elem1:"poison_gas", elem2:null, chance:0.1 },
"iron": { elem1:null, elem2:"rust", chance:0.1 },
"copper": { elem1:null, elem2:"oxidized_copper", chance:0.1 },
"pollen": { elem2:null, chance:0.1 },
"antidote": { elem2:null, chance:0.1 },
},
tempHigh: 111,
stateHigh: ["salt","steam"],
tempLow: -15.3,
viscosity: 0.956,
state: "liquid",
category:"liquids",
density: 1210,
stain: 0.1
},
"chlorine": {
color: "#a5ac50",
behavior: behaviors.GAS,
reactions: {
"water": { elem1: "pool_water", elem2:null },
"hydrogen": { elem1: "acid_gas", elem2:null },//hydrochloric acid
"dirty_water": { elem2:"water" },
"ammonia": { elem1:"poison_gas", elem2:null },
"liquid_ammonia": { elem1:"poison_gas", elem2:null },
"oil": { elem1:null, elem2:"explosion", burning2:true },
"lamp_oil": { elem1:null, elem2:"explosion", burning2:true },
"sodium": { elem1:"fire", elem2:"salt" },
"molten_sodium": { elem1:"fire", elem2:"salt" },
"root": { elem2:null, chance:0.025 },
"tree_branch": { elem2:"wood", chance:0.015 },
"pistil": { elem2:"dead_plant", chance:0.025 },
"head": { func:behaviors.KILLPIXEL2, chance:0.005 }
},
tempLow: -36.04,
stateLow: "liquid_chlorine",
state: "gas",
category:"gases",
density: 3.2,
stain: 0.005
},
"liquid_chlorine": {
color: "#f4d217",
behavior: behaviors.LIQUID,
reactions: {
"water": { elem1: "acid", elem2:null },
"steam": { elem2: "acid_gas", elem1:null },
"ammonia": { elem1:"poison", elem2:null },
"liquid_ammonia": { elem1:"poison", elem2:null },
},
temp: -36.04,
tempHigh: -34.04,
stateHigh: "chlorine",
tempLow: -101.5,
state: "liquid",
category:"states",
density: 1562.5,
stain: 0.01,
hidden: true
},
"dye": {
color: ["#ff0000","#ff8800","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff"],
behavior: behaviors.LIQUID,
reactions: {
"water": { elem1:null, chance:0.05 },
"salt_water": { elem1:null, chance:0.05 },
"sugar_water": { elem1:null, chance:0.05 },
"seltzer": { elem1:null, chance:0.05 },
"dirty_water": { elem1:null, chance:0.05 },
"pool_water": { elem1:null, chance:0.05 }
},
customColor: true,
stain: 0.66,
tempHigh: 100,
stateHigh: "smoke",
category: "liquids",
state: "liquid",
density: 998,
stainSelf: true
},
"ink": {
color: "#171717",
behavior: behaviors.LIQUID,
reactions: {
"water": { elem1:null, chance:0.01 },
"salt_water": { elem1:null, chance:0.01 },
"sugar_water": { elem1:null, chance:0.01 },
"seltzer": { elem1:null, chance:0.01 },
"dirty_water": { elem1:null, chance:0.01 },
"pool_water": { elem1:null, chance:0.01 }
},
stain: 0.66,
tempHigh: 100,
stateHigh: "smoke",
tempLow: 0,
stateLowName: "frozen_ink",
category: "liquids",
state: "liquid",
density: 1074.3
},
"mercury": {
color: ["#53574b","#65686a"],
behavior: behaviors.LIQUID,
reactions: {
"gold": { elem1:null, elem2:"amalgam", chance:0.01 },
"zinc": { elem1:null, elem2:"amalgam", chance:0.01 },
"sodium": { elem1:["pop","electric"], elem2:"amalgam", chance:0.01, temp2:600 },
"molten_sodium": { elem1:["pop","electric"], elem2:"amalgam", chance:0.01, temp2:600 },
"aluminum": { elem1:null, elem2:"amalgam", chance:0.01 },
"tin": { elem1:null, elem2:"amalgam", chance:0.01 },
"lead": { elem1:null, elem2:"amalgam", chance:0.01 },
"silver": { elem1:null, elem2:"amalgam", chance:0.01 },
"copper": { elem1:null, elem2:"amalgam", chance:0.01 },
"gold_coin": { elem1:null, elem2:"amalgam", chance:0.01 },
"rose_gold": { elem1:null, elem2:"amalgam", chance:0.01 },
"water": { elem1:null, elem2:"dirty_water" },
"salt_water": { elem1:null, elem2:"dirty_water" },
"sugar_water": { elem1:null, elem2:"dirty_water" },
"seltzer": { elem1:null, elem2:"dirty_water" },
"neutron": { elem1:"gold_coin", chance:0.005 }
},
viscosity: 1.53,
tempLow: -38.83,
stateLowName: "solid_mercury",
tempHigh: 356.73,
category:"liquids",
state: "liquid",
density: 13545,
conduct: 0.85
},
"mercury_gas": {
density: 12800,
conduct: 0.02,
colorOn: "#5a96e0"
},
"solid_mercury": {
conduct: 0.99
},
"blood": {
color: ["#ff0000","#ee0000"],
behavior: behaviors.LIQUID,
reactions: {
"vaccine": { elem1:"antibody", elem2:null },
"plague": { elem1:"infection", elem2:null },
"rotten_meat": { elem1:"infection" },
"rotten_cheese": { elem1:"infection" },
"virus": { elem1:"infection", elem2:null },
"cancer": { elem1:"infection" },
"cyanide": { elem1:"infection", elem2:null },
"cyanide_gas": { elem1:"infection", elem2:null },
"mushroom_spore": { elem1:"infection", elem2:null },
"mushroom_gill": { elem1:"infection" },
"dirty_water": { elem1:"infection", elem2:null },
"rad_steam": { elem1:"infection" },
"rad_glass": { elem1:"infection" },
"rad_shard": { elem1:"infection" },
"rad_cloud": { elem1:"infection" },
"fallout": { elem1:"infection" },
"rust": { elem1:"infection", chance:0.05 },
"oxidized_copper": { elem1:"infection", chance:0.05 },
"rat": { elem1:"infection", chance:0.075 },
"flea": { elem1:"infection", chance:0.03 },
"worm": { elem1:"infection", chance:0.03 },
"dirt": { elem1:null, elem2:"mud" },
"sand": { elem1:null, elem2:"wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
"mercury": { elem1:"infection", elem2:null, chance:0.05 },
"oxygen": { elem2:null, chance:0.05 },
"carbon_dioxide": { elem2:null, chance:0.05 },
"alcohol": { elem1:[null,"dna"], chance:0.02 }
},
viscosity: 10,
tempHigh: 124.55,
stateHigh: ["steam","salt","oxygen"],
tempLow: 0,
category:"liquids",
state: "liquid",
density: 1060,
stain: 0.05
},
"vaccine": {
color: "#e0d0ad",
behavior: behaviors.LIQUID,
reactions: {
"infection": { elem1:null, elem2:"antibody", chance:0.1 },
"antibody": { elem1:null, chance:0.0025 },
"plague": { elem2:null, chance:0.1 },
"virus": { elem2:null, chance:0.1 },
"cancer": { elem2:null, chance:0.01 },
"rotten_meat": { elem2:"meat", chance:0.1 },
"rotten_cheese": { elem2:"cheese", chance:0.1 },
"dirt": { elem1:null, elem2:"mud" },
"sand": { elem1:null, elem2:"wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
},
viscosity: 2.6,
tempHigh: 124.55,
stateHigh: "steam",
category:"liquids",
state: "liquid",
density: 1125,
isFood: true,
stain: -0.05
},
"antibody": {
color: "#ff4040",
behavior: behaviors.LIQUID,
reactions: {
"blood": { elem2:"antibody", chance:0.01 },
"infection": { elem2:"antibody", chance:0.1 },
"cancer": { elem2:null, chance:0.01 },
"worm": { elem2:null, chance:0.01 },
"rotten_meat": { elem2:"meat", chance:0.1 },
"rotten_cheese": { elem2:"cheese", chance:0.1 },
"poison": { elem1:"antidote", elem2:null, chance:0.03 },
"alcohol": { elem1:[null,"dna"], chance:0.02 },
"dirt": { elem1:null, elem2:"mud" },
"sand": { elem1:null, elem2:"wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
},
viscosity: 6.3,
tempHigh: 124.55,
stateHigh: ["steam","salt","oxygen"],
tempLow: 0,
category:"liquids",
hidden: true,
state: "liquid",
density: 1060,
stain: 0.05
},
"infection": {
color: ["#cf005d","#be004c"],
behavior: behaviors.LIQUID,
reactions: {
"blood": { elem2:"infection", chance:0.01 },
"frog": { elem2:"rotten_meat", chance:0.005 },
"fish": { elem2:"rotten_meat", chance:0.005 },
"meat": { elem2:"rotten_meat", chance:0.005 },
"alcohol": { elem1:"blood", chance:0.2 },
"dirt": { elem1:null, elem2:"mud" },
"sand": { elem1:null, elem2:"wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
},
viscosity: 15,
tempHigh: 124.55,
stateHigh: ["plague","plague","plague","salt","oxygen"],
tempLow: 0,
category:"liquids",
hidden: true,
state: "liquid",
density: 1060,
stain: 0.05
},
"poison": {
color: "#00ff00",
behavior: behaviors.LIQUID,
reactions: {
"blood": { elem1:null, elem2:"infection" },
"water": { elem1:null, elem2:"dirty_water" },
"soap": { elem1:null, chance:0.02 },
"plant": { elem1:null, elem2:"dead_plant" },
"evergreen": { elem1:null, elem2:"dead_plant" },
"cactus": { elem1:null, elem2:"dead_plant" },
"grass": { elem1:null, elem2:"dead_plant" },
"vine": { elem1:null, elem2:"dead_plant" },
"algae": { elem1:null, elem2:null },
"mushroom_spore": { elem1:null, elem2:null },
"lichen": { elem1:null, elem2:null },
"yeast": { elem1:null, elem2:null },
"rat": { elem1:null, elem2:"rotten_meat" },
"frog": { elem1:null, elem2:"rotten_meat" },
"tadpole": { elem2:null },
"fish": { elem1:null, elem2:"rotten_meat" },
"bird": { elem1:null, elem2:"rotten_meat" },
"head": { elem1:null, elem2:"rotten_meat" },
"body": { elem1:null, elem2:"rotten_meat" },
"homunculus": { elem1:null, elem2:"rotten_meat" },
"ant": { elem1:null, elem2:"dead_bug" },
"worm": { elem1:null, elem2:"dead_bug" },
"fly": { elem1:null, elem2:"dead_bug" },
"firefly": { elem1:null, elem2:"dead_bug" },
"bee": { elem1:null, elem2:"dead_bug" },
"stink_bug": { elem1:null, elem2:"dead_bug" },
"termite": { elem1:null, elem2:"dead_bug" },
"flea": { elem1:null, elem2:"dead_bug" },
"slug": { elem1:null, elem2:"slime" },
"snail": { elem1:null, elem2:"quicklime" },
"sapling": { elem1:null, elem2:"dead_plant" },
"root": { elem1:null, elem2:"dead_plant" },
"flower_seed": { elem1:null, elem2:"dead_plant" },
"pistil": { elem1:null, elem2:"dead_plant" },
"petal": { elem1:null, elem2:"dead_plant" },
"grass_seed": { elem1:null, elem2:"dead_plant" },
"meat": { elem1:null, elem2:"rotten_meat" },
"cheese": { elem1:null, elem2:"rotten_cheese" },
"tree_branch": { elem1:null, elem2:"wood" },
"mushroom_cap": { elem1:null, elem2:null, chance:0.01 },
"mushroom_gill": { elem1:null, elem2:null, chance:0.01 },
"mushroom_stalk": { elem1:null, elem2:null, chance:0.01 },
"hyphae": { elem1:null, elem2:null, chance:0.02 },
"mycelium": { elem1:null, elem2:"dirt", chance:0.1 },
"pollen": { elem2:null, chance:0.01 },
"mushroom_spore": { elem1:null, elem2:null, chance:0.1 },
"bone_marrow": { elem1:null, elem2:"rotten_meat" },
"head": { elem1:null, elem2:"rotten_meat" },
"body": { elem1:null, elem2:"rotten_meat" },
"hair": { elem1:null, elem2:null, chance:0.01 },
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
},
viscosity: 2,
tempHigh: 110,
tempLow: 0,
category:"liquids",
state: "liquid",
density: 1060
},
"poison_gas": {
color: "#98f5b0",
tempLow: 0,
stateLow: "poison",
density: 1.6
},
"poison_ice": {
color: "#9eff9e"
},
"antidote": {
color: "#c9b836",
behavior: behaviors.LIQUID,
reactions: {
"poison": { elem1:null, elem2:null, chance:0.1 },
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
},
viscosity: 2,
tempHigh: 124.55,
stateHigh: ["steam","salt","oxygen"],
category:"liquids",
state: "liquid",
density: 1060,
stain: -0.05
},
"tea": {
color: "#6c4317",
behavior: behaviors.LIQUID,
reactions: {
"stench": { elem2:null },
"flea": { elem2:null, chance:0.01 },
"oxygen": { elem2:"fragrance", chance:0.01 },
"infection": { elem2:"blood", chance:0.005 },
"plague": { elem2:null, chance:0.004 },
"sugar": { elem2:null, color1:"#8f5a21", chance:0.005},
"honey": { elem2:null, color1:"#8f5a21", chance:0.005},
"milk": { elem2:null, color1:"#9c6c38", chance:0.005},
"cream": { elem2:null, color1:"#9c6c38", chance:0.005},
"ice_cream": { elem2:null, color1:"#9c6c38", chance:0.005},
},
tempHigh: 125,
stateHigh: ["steam","fragrance",null],
temp: 80,
tempLow: 0,
category:"liquids",
state: "liquid",
density: 1001,
stain: -0.1,
hidden: true,
isFood: true
},
"coffee": {
color: "#24100b",
behavior: behaviors.LIQUID,
reactions: {
"stench": { elem2:null },
"oxygen": { elem2:"fragrance", chance:0.01 },
"sugar": { elem2:null, color1:"#99552A", chance:0.005},
"honey": { elem2:null, color1:"#99552A", chance:0.005},
"pumpkin_seed": { elem2:null, color1:"#6A2F03", chance:0.005},
"milk": { elem2:"foam", color1:"#CA9D68", chance:0.005},
"nut_milk": { elem2:"foam", color1:"#CA9D68", chance:0.005},
"cream": { elem2:"foam", color1:"#CA9D68", chance:0.005},
"ice_cream": { elem2:null, color1:"#CA9D68", chance:0.005},
"chocolate": { elem2:null, color1:"#6A3517", chance:0.005},
"melted_chocolate": { elem2:null, color1:"#6A3517", chance:0.005},
"water": { elem2:"coffee", tempMin:70, chance:0.2 },
"salt_water": { elem2:"coffee", tempMin:70, chance:0.2 },
"sugar_water": { elem2:"melted_chocolate", tempMin:60, chance:0.3 },
"seltzer": { elem2:"coffee", tempMin:70, chance:0.2 },
},
tempHigh: 130,
stateHigh: ["steam","fragrance",null],
temp: 80,
tempLow: 0,
category:"liquids",
state: "liquid",
density: 1001.74,
stain: 0.01,
hidden: true,
isFood: true
},
"honey": {
color: ["#f6ce1a","#e79001","#bb5503"],
behavior: behaviors.LIQUID,
onMix: function(pixel1,pixel2) {
if (Math.random() < 0.05 && pixel2.element === "sugar_water") {
changePixel(pixel1,"wax")
}
},
viscosity: 10000,
tempHigh: 71.11,
stateHigh: "caramel",
category:"liquids",
state: "liquid",
density: 1420,
isFood: true
},
"sap": {
color: ["#b67f18","#c86305","#cf7a19","#e4ae3a"],
behavior: behaviors.LIQUID,
reactions: {
"dead_bug": { elem1:"amber", elem2:null, chance:0.1 },
"ant": { elem1:"amber", elem2:null, chance:0.1 },
"fly": { elem1:"amber", elem2:null, chance:0.1 },
"flea": { elem1:"amber", elem2:null, chance:0.1 },
"termite": { elem1:"amber", elem2:null, chance:0.1 },
"worm": { elem1:"amber", elem2:null, chance:0.1 },
"bee": { elem1:"amber", elem2:null, chance:0.1 },
"firefly": { elem1:"amber", elem2:null, chance:0.1 },
"stinkbug": { elem1:"amber", elem2:null, chance:0.1 },
"slug": { elem1:"amber", elem2:null, chance:0.1 },
"snail": { elem1:"amber", elem2:null, chance:0.1 },
},
tempHigh: 103.05,
stateHigh: ["sugar","smoke","smoke"],
tempLow: 0,
stateLowName: "amber",
burn: 40,
burnTime: 15,
burnInto: "fire",
category:"liquids",
state: "liquid",
viscosity: 15,
density: 1400
},
"caramel": {
color: "#e89a51",
behavior: behaviors.LIQUID,
reactions: {
"grape": { elem1:null, elem2:"jelly", chance:0.005, tempMin:100 },
"salt": { elem2:null, color1:"#ffbd80", chance:0.005},
},
viscosity: 500,
tempLow: -20,
stateLow: "candy",
tempHigh: 204.44,
stateHigh: "smoke",
category: "liquids",
state: "liquid",
stain: 0.01,
density: 850,
isFood: true
},
"molasses": {
color: ["#210c06","#170804"],
behavior: behaviors.LIQUID,
viscosity: 7500,
tempHigh: 1000,
stateHigh: ["fire","smoke","steam"],
category:"liquids",
state: "liquid",
density: 1600,
stain: 0.05,
isFood: true
},
"ketchup": {
color: "#ff3119",
behavior: behaviors.LIQUID,
reactions: {
"rust": { elem2:"iron", chance:0.01 },
"oxidized_copper": { elem2:"copper", chance:0.01 },
"baking_soda": { "elem1":"carbon_dioxide", elem2:"foam", chance:0.01 },
},
viscosity: 50000,
tempHigh: 260,
stateHigh: ["carbon_dioxide","methane","steam","salt","sugar"],
category:"liquids",
state: "liquid",
density: 1235,
stain: 0.05,
isFood: true
},
"mayo": {
color: "#fcffbd",
behavior: behaviors.LIQUID,
reactions: {
"glue": { elem2:null, chance:0.01 },
"oil": { elem2:null, chance:0.01 },
"sap": { elem2:null, chance:0.01 },
},
viscosity: 3491,
tempHigh: 100.6,
stateHigh: ["steam","carbon_dioxide","methane"],
category:"liquids",
state: "liquid",
density: 910,
stain: 0.01,
isFood: true
},
"grease": {
color: "#cf9251",
behavior: behaviors.LIQUID,
reactions: {
"caustic_potash": { elem1:"soap", elem2:"soap" },
"toast": { color2:["#A84B1E","#C96619","#F9B042"], tempMin:160, chance:0.05 },
"crumb": { color2:["#A84B1E","#C96619","#F9B042"], tempMin:160, chance:0.05 },
"baked_batter": { color2:["#A84B1E","#C96619","#F9B042"], tempMin:160, chance:0.05 },
"baked_potato": { color2:["#A84B1E","#C96619","#F9B042"], tempMin:160, chance:0.05 },
},
viscosity: 70,
tempHigh: 250,
stateHigh: ["fire","smoke","smoke","smoke"],
tempLow: 20,
stateLowName: "fat",
temp: 45,
category:"liquids",
state: "liquid",
density: 919,
isFood: true,
hidden: true
},
"fat": {
color: "#dbc9b6",
tempHigh: 45,
stateHigh: "grease",
reactions: {
"caustic_potash": { elem1:"soap", elem2:null }
},
},
"melted_chocolate": {
color: "#3b160b",
behavior: behaviors.LIQUID,
tempLow: 0,
stateLow: "chocolate",
tempHigh: 99,
stateHigh: ["steam","sugar"],
category: "states",
viscosity: 40,
state: "liquid",
density: 1325,
hidden: true,
stain: 0.05,
isFood: true
},
"liquid_hydrogen": {
color: "#97afcf",
behavior: behaviors.LIQUID,
reactions: {
"liquid_oxygen": { elem1:"ice", elem2:null },
"oxygen": { elem1:"ice", elem2:null }
},
category: "states",
burn: 100,
burnTime: 2,
temp: -255.879,
tempHigh: -252.879,
stateHigh: "hydrogen",
tempLow: -259.2,
state: "liquid",
density: 71,
hidden: true
},
"liquid_oxygen": {
color: "#00ad99",
behavior: behaviors.LIQUID,
reactions: {
"hydrogen": { elem1:"ice", elem2:null }
},
category: "liquids",
burn: 100,
burnTime: 2,
temp: -190,
tempHigh: -182.962,
tempLow: -218.8,
stateHigh: "oxygen",
state: "liquid",
density: 1141
},
"liquid_nitrogen": {
color: "#d3e1e3",
behavior: behaviors.LIQUID,
category: "liquids",
temp: -209.86,
tempHigh: -195.795,
stateHigh: "nitrogen",
tempLow: -259.86,
stateLow: "nitrogen_ice",
state: "liquid",
density: 804
},
"liquid_helium": {
color: "#e3d3d3",
behavior: behaviors.SUPERFLUID,
category: "states",
temp:-269,
tempHigh: -268.95,
stateHigh: "helium",
state: "liquid",
density: 145,
viscosity: 0,
hidden: true
},
"sodium": {
color: ["#484849","#5d5e5f","#6b6968","#747775"],
tick: function(pixel) {
behaviors.POWDER(pixel);
for (var i = 0; i < adjacentCoords.length; i++) {
var x = pixel.x+adjacentCoords[i][0];
var y = pixel.y+adjacentCoords[i][1];
if (isEmpty(x,y)) {
if (Math.random() < 0.005) { deletePixel(pixel.x,pixel.y) }
break
} } },
reactions: {
"chlorine": { elem1:"salt", elem2:"pop" },
"vinegar": { elem1:"sodium_acetate", elem2:[null,null,null,"hydrogen"], attr1:{"foam":15} },
"water": { elem1:["pop","pop","pop","hydrogen"], chance:0.01, temp2:250 },
"salt_water": { elem1:["pop","pop","pop","hydrogen"], chance:0.01, temp2:250 },
"sugar_water": { elem1:["pop","pop","pop","hydrogen"], chance:0.01, temp2:250 },
"dirty_water": { elem1:["pop","pop","pop","hydrogen"], chance:0.01, temp2:250 },
"seltzer": { elem1:["pop","pop","pop","hydrogen"], chance:0.01, temp2:250 },
"pool_water": { elem1:["pop","pop","pop","hydrogen"], chance:0.01, temp2:250 },
"primordial_soup": { elem1:["pop","pop","pop","hydrogen"], chance:0.01, temp2:250 },
"acid": { elem1:"explosion" }
},
tempHigh: 97.794,
category: "powders",
state: "solid",
density: 968,
conduct: 0.85,
hardness: 0.05
},
"molten_sodium": {
tempLow: 97.794,
tempHigh: 882.8,
fireColor: "#ffff00",
reactions: {
"chlorine": { elem1:"salt", elem2:"pop" },
"vinegar": { elem1:"sodium_acetate", elem2:null, attr1:{"foam":15} },
"water": { elem1:["pop","pop","pop","hydrogen"], chance:0.01, temp2:250 },
"salt_water": { elem1:["pop","pop","pop","hydrogen"], chance:0.01, temp2:250 },
"sugar_water": { elem1:["pop","pop","pop","hydrogen"], chance:0.01, temp2:250 },
"dirty_water": { elem1:["pop","pop","pop","hydrogen"], chance:0.01, temp2:250 },
"seltzer": { elem1:["pop","pop","pop","hydrogen"], chance:0.01, temp2:250 },
"pool_water": { elem1:["pop","pop","pop","hydrogen"], chance:0.01, temp2:250 },
"primordial_soup": { elem1:["pop","pop","pop","hydrogen"], chance:0.01, temp2:250 },
"acid": { elem1:"explosion" }
},
density: 927,
fireElement: null
},
"sodium_gas": {
color: "#5d5e5f",
fireElement: null
},
"calcium": {
color: ["#544E45","#6A635E","#6E6A61","#756F62","#918A7B"],
tick: function(pixel) {
behaviors.POWDER(pixel);
for (var i = 0; i < adjacentCoords.length; i++) {
var x = pixel.x+adjacentCoords[i][0];
var y = pixel.y+adjacentCoords[i][1];
if (isEmpty(x,y)) {
if (Math.random() < 0.005) { changePixel(pixel,"quicklime") }
break
} } },
reactions: {
"oxygen": { elem1:"quicklime", elem2:null },
"water": { elem1:["slaked_lime","pop"], elem2:["hydrogen","bubble"], chance:0.005, temp2:350 },
"salt_water": { elem1:["slaked_lime","pop"], elem2:["hydrogen","bubble"], chance:0.005, temp2:350 },
"sugar_water": { elem1:["slaked_lime","pop"], elem2:["hydrogen","bubble"], chance:0.005, temp2:350 },
"dirty_water": { elem1:["slaked_lime","pop"], elem2:["hydrogen","bubble"], chance:0.005, temp2:350 },
"seltzer": { elem1:["slaked_lime","pop"], elem2:["hydrogen","bubble"], chance:0.005, temp2:350 },
"pool_water": { elem1:["slaked_lime","pop"], elem2:["hydrogen","bubble"], chance:0.005, temp2:350 },
},
tempHigh: 842,
category: "powders",
state: "solid",
density: 1550,
conduct: 0.40,
hardness: 0.2,
fireColor: "#ff6b21"
},
"molten_calcium": {
burn: 10,
burnInto: ["flash","smoke","pop"],
density: 1378,
fireElement: null
},
"limestone": {
color: ["#c5b79c","#d9ccb2","#f8f1db","#fcfaeb"],
behavior: behaviors.STURDYPOWDER,
tempHigh: 825,
stateHigh: ["quicklime","quicklime","quicklime","quicklime","quicklime","quicklime","carbon_dioxide"],
category: "land",
state: "solid",
density: 2100,
hardness: 0.3,
breakInto: ["quicklime","dust","gravel"]
},
"quicklime": {
color: "#e9ebe7",
behavior: behaviors.POWDER,
reactions: {
"carbon_dioxide": { elem1:"limestone", chance:0.1 },
"ant": { elem1:null, elem2:"dead_bug", chance:0.2 },
"fly": { elem1:null, elem2:"dead_bug", chance:0.2 },
"firefly": { elem1:null, elem2:"dead_bug", chance:0.2 },
"bee": { elem1:null, elem2:"dead_bug", chance:0.2 },
"stink_bug": { elem1:null, elem2:"dead_bug", chance:0.2 },
"termite": { elem1:null, elem2:"dead_bug", chance:0.2 },
"flea": { elem1:null, elem2:"dead_bug", chance:0.2 },
},
tempHigh: 4662,
stateHigh: "molten_calcium",
category: "land",
state: "solid",
density: 1025,
hardness: 0.23,
hidden: true
},
"slaked_lime": {
color: "#A8A19D",
behavior: behaviors.STURDYPOWDER,
reactions: {
"wet_sand": { elem1:"cement", elem2:null, chance:0.2 },
"sand": { elem1:"cement", elem2:null, chance:0.2 },
"ash": { elem1:"cement", elem2:null, chance:0.2 },
"clay_shard": { elem1:"cement", elem2:null, chance:0.2 },
"porcelain_shard": { elem1:"cement", elem2:null, chance:0.2 },
"milk": { elem1:"glue", elem2:"glue", chance:0.02 },
},
tempHigh: 580,
stateHigh: "quicklime",
category: "land",
hidden: true,
state: "solid",
density: 2211,
hardness: 0.13,
},
"potassium": {
color: ["#C9CFCD","#B4BDBA","#98A1A0","#7C8486","#636B6E"],
behavior: behaviors.POWDER,
reactions: {
"chlorine": { elem1:"potassium_salt", elem2:null, chance:0.05 },
"water": { elem1:["caustic_potash","pop"], elem2:["hydrogen","pop","fire"], chance:0.01, temp2:400 },
"steam": { elem1:["caustic_potash","pop"], elem2:["hydrogen","pop","fire"], chance:0.01, temp2:400 },
"smog": { elem1:["caustic_potash","pop"], elem2:["hydrogen","pop","fire"], chance:0.01, temp2:400 },
"salt_water": { elem1:["caustic_potash","pop"], elem2:["hydrogen","pop","fire"], chance:0.01, temp2:400 },
"sugar_water": { elem1:["caustic_potash","pop"], elem2:["hydrogen","pop","fire"], chance:0.01, temp2:400 },
"dirty_water": { elem1:["caustic_potash","pop"], elem2:["hydrogen","pop","fire"], chance:0.01, temp2:400 },
"seltzer": { elem1:["caustic_potash","pop"], elem2:["hydrogen","pop","fire"], chance:0.01, temp2:400 },
"pool_water": { elem1:["caustic_potash","pop"], elem2:["hydrogen","pop","fire"], chance:0.01, temp2:400 },
"electric": { elem1:[null,"pop"], elem2:["pop","fire"], chance:0.05, temp2:400 },
},
tempHigh: 63.5,
category: "powders",
state: "solid",
density: 890,
conduct: 0.75,
hardness: 0.5,
burn: 20,
fireColor: "#C291FE"
},
"molten_potassium": {
color: "#4B3C3B",
reactions: {
"water": { elem1:["caustic_potash","pop"], elem2:["hydrogen","pop","fire"], chance:0.01, temp2:400 },
"steam": { elem1:["caustic_potash","pop"], elem2:["hydrogen","pop","fire"], chance:0.01, temp2:400 },
"salt_water": { elem1:["caustic_potash","pop"], elem2:["hydrogen","pop","fire"], chance:0.01, temp2:400 },
"sugar_water": { elem1:["caustic_potash","pop"], elem2:["hydrogen","pop","fire"], chance:0.01, temp2:400 },
"dirty_water": { elem1:["caustic_potash","pop"], elem2:["hydrogen","pop","fire"], chance:0.01, temp2:400 },
"seltzer": { elem1:["caustic_potash","pop"], elem2:["hydrogen","pop","fire"], chance:0.01, temp2:400 },
"pool_water": { elem1:["caustic_potash","pop"], elem2:["hydrogen","pop","fire"], chance:0.01, temp2:400 },
},
stateLow: "potassium",
tempLow: 63.5,
burn: 20,
burnInto: ["caustic_potash","pop"],
fireElement: null
},
"magnesium": {
color: ["#D0D0D0","#A8A8A8","#ADADAD"],
behavior: behaviors.POWDER,
tempHigh: 63.5,
category: "powders",
state: "solid",
density: 890,
conduct: 0.05 ,
hardness: 0.5,
burn: 20,
fireColor: "#f9ebff",
fireElement: "flash"
},
"molten_magnesium": {
color: "#768487",
fireElement: "flash",
burnInto: "flash",
tempLow: 64,
stateLow: "magnesium"
},
"thermite": {
color: ["#5d4947","#5b3c42","#372a2d"],
behavior: behaviors.POWDER,
tick: function(pixel) {
if (pixel.burning) {
changePixel(pixel,"molten_thermite");
pixel.temp = 2200;
}
},
tempHigh: 660,
burn: 100,
burnTime: 1000,
category: "powders",
density: 700,
state: "solid",
hardness: 0.325
},
"molten_thermite": {
tick: function(pixel) {
pixel.temp ++;
},
reactions: {
"ice": { "elem1":"explosion" }
}
},
"slag": {
color: ["#4b3a2d","#6a5447","#6b5b53","#675851","#78756e"],
behavior: behaviors.POWDER,
tempHigh: 1380,
category: "powders",
density: 2400,
state: "solid",
conduct: 0.03,
hardness: 0.5,
breakInto: "gravel"
},
"amalgam": {
color: ["#6b5535","#96784f","#604928","#a69070"],
reactions: {
"salt_water": { elem1:"mercury", elem2:["sodium","hydrogen","hydrogen"], charged:true, chance:0.01 },
},
behavior: behaviors.SUPPORT,
tempHigh: 223,
category:"powders",
state: "solid",
density: 13920,
hardness: 0.1,
hidden: true,
conduct: 0.37,
},
"molten_aluminum": {
reactions: {
"rust": { elem1:null, elem2:"thermite" },
"oxidized_copper": { elem1:null, elem2:"thermite" }
},
density: 2375
},
"molten_zinc": {
reactions: {
"rust": { elem1:null, elem2:"thermite" },
"oxidized_copper": { elem1:null, elem2:"thermite" }
},
density: 6570
},
"neon": {
color: "#bababa",
behavior: behaviors.GAS,
colorOn: ["#ff0000","#d01822","#fe5c0c"],
tempLow: -246,
stateLow: "liquid_neon",
category: "gases",
density: 0.9002,
state: "gas",
conduct: 0.86
},
"liquid_neon": {
color: "#d1d1d1",
behavior: behaviors.LIQUID,
colorOn: ["#ff0000","#d01822","#fe5c0c"],
temp: -247,
tempHigh: -246,
stateHigh: "neon",
tempLow: -248.6,
category: "states",
hidden: true,
density: 1207,
state: "liquid",
conduct: 0.83
},
"smog": {
color: "#989398",
behavior: [
"XX|M2%5|XX",
"M1%8|XX|M1%8",
"XX|M2%5|XX",
],
reactions: {
"plant": { elem1:"cloud" },
"evergreen": { elem1:"cloud" },
"cactus": { elem1:"cloud" },
"algae": { elem1:"cloud" },
},
temp: 100,
tempLow: 47.5,
stateLow: "dirty_water",
category: "gases",
density: 590.3,
state: "gas",
conduct: 0.03,
stain: 0.0035
},
"stench": {
color: "#6ab066",
behavior: [
"M2|M1|M2",
"M1|DL%0.5|M1",
"M2|M1|M2",
],
reactions: {
"oxygen": { elem2:"stench", chance:0.01 },
"water": { elem1:null, elem2:"dirty_water" },
"nitrogen": { elem2:"stench" },
"baking_soda": { elem1:null },
"fire": { elem1:null },
"bubble": { elem1:null },
"foam": { elem1:null },
},
category: "gases",
tempHigh: 1000,
stateHigh: "fire",
tempLow: -15,
stateLowName: "liquid_stench",
state: "gas",
density: 1.293
},
"liquid_stench": {
color: "#3ea346"
},
"fragrance": {
color: "#967bb6",
behavior: [
"M2|M1|M2",
"M1|DL%0.5|M1",
"M2|M1|M2",
],
reactions: {
"stench": { elem2:null },
"oxygen": { elem2:"fragrance", chance:0.01 },
"dirty_water": { elem1:null, elem2:"water" },
"rotten_meat": { elem1:null },
"rotten_cheese": { elem1:null },
"fly": { elem1:null },
},
tempHigh: 1000,
stateHigh: "fire",
tempLow: -15,
stateLowName: "perfume",
category: "gases",
state: "gas",
density: 1.292
},
"perfume": {
color: "#9656e3",
reactions: {
"liquid_stench": { elem2:null },
},
category: "liquids"
},
"cyanide": {
color: "#b6ccb6",
behavior: behaviors.LIQUID,
reactions: {
"frog": { elem2:"rotten_meat" },
"ant": { elem2:null },
"bee": { elem2:null },
"fish": { elem2:"rotten_meat" },
"firefly": { elem2:null },
"head": { elem2:"rotten_meat" },
"body": { elem2:"rotten_meat" },
},
tempHigh: 26,
tempLow: -13.29,
burn: 100,
burnTime: 1,
state: "liquid",
density: 687,
category: "liquids",
hidden: true
},
"cyanide_gas": {
reactions: {
"frog": { elem2:"rotten_meat" },
"ant": { elem2:null },
"bee": { elem2:null },
"fish": { elem2:"rotten_meat" },
"firefly": { elem2:null },
"head": { elem2:"rotten_meat" },
"body": { elem2:"rotten_meat" },
},
tempHigh: 550,
stateHigh: "fire",
burn: 100,
burnTime: 1,
density: 941,
category: "gases"
},
"ozone": {
color: "#80a4ff",
behavior: [
"XX|XX|XX",
"M1%7|XX|M1%7",
"XX|XX|XX",
],
reactions: {
"carbon_dioxide": { elem1:null, elem2:null, chance:0.05 },
"anesthesia": { elem1:null, elem2:null, chance:0.05 },
"copper": { elem1:"oxygen", elem2:"oxidized_copper", chance:0.1 },
"bronze": { elem1:"oxygen", elem2:"oxidized_copper", chance:0.05 },
"iron": { elem1:"oxygen", elem2:"rust", chance:0.05 },
"steel": { elem1:"oxygen", elem2:"rust", chance:0.04 },
"charcoal": { elem1:"oxygen", elem2:"carbon_dioxide", chance:0.025 },
"dirty_water": { elem1:null, elem2:"water" },
"stench": { elem1:null, elem2:null },
"pyrocumulus": { elem1:null, elem2:null },
"smoke": { elem1:null, elem2:null, chance:0.005 },
"yeast": { elem2:null, chance:0.1 },
"cell": { elem2:null, chance:0.1 },
"cancer": { elem2:null, chance:0.025 },
"infection": { elem2:"blood", chance:0.1 },
"rat": { elem2:"rotten_meat", chance:0.05 },
"fish": { elem2:"rotten_meat", chance:0.05 },
"worm": { elem2:null, chance:0.05 },
"frozen_worm": { elem2:null, chance:0.05 },
"frog": { elem2:null, chance:0.05 },
"plague": { elem2:null, chance:0.05 },
"chlorine": { elem2:null, chance:0.05 },
"plant": { elem1:null, elem2:"dead_plant", chance:0.25 },
"evergreen": { elem1:null, elem2:"dead_plant", chance:0.25 },
"cactus": { elem1:null, elem2:"dead_plant", chance:0.2 },
"grass": { elem1:null, elem2:"dead_plant", chance:0.25 },
"vine": { elem1:null, elem2:"dead_plant", chance:0.25 },
"tree_branch": { elem1:null, elem2:"wood", chance:0.25 },
"algae": { elem1:null, elem2:null, chance:0.25 },
},
category:"gases",
temp: -15,
tempLow: -112,
stateLow: "liquid_oxygen",
state: "gas",
stain: -0.1,
density: 2.14
},
"cloud": {
color: "#d5dce6",
behavior: [
"XX|XX|XX",
"XX|CO:1%5|M1%2.5 AND BO",
"XX|XX|XX",
],
reactions: {
"rain_cloud": { elem1:"rain_cloud", temp1:-20 },
"electric": { elem1:"rain_cloud", temp1:-20 },
"cloud": { elem1:"rain_cloud", elem2:"rain_cloud", temp1:-20, temp2:-20, charged:true },
"anesthesia": { elem1:"acid_cloud", elem2:null, chance:0.05 },
"sand": { elem2: "sandstorm", chance:0.2, "y":[0,12], "setting":"clouds" },
},
category:"gases",
temp: 110,
tempLow: 100,
stateLow: "rain_cloud",
state: "gas",
density: 0.4,
ignoreAir: true,
conduct: 0.03
},
"rain_cloud": {
color: "#636b78",
behavior: [
"XX|XX|XX",
"XX|CH:water%0.05|M1%2.5 AND BO",
"CR:electric%0.05|CR:electric%0.05|CR:electric%0.05",
],
reactions: {
"anesthesia": { elem1:"acid_cloud", elem2:null, chance:0.05 },
"sand": { elem2: "sandstorm", chance:0.2, "y":[0,12], "setting":"clouds" },
"wet_sand": { elem2: "sandstorm", chance:0.2, "y":[0,12], "setting":"clouds" },
},
category:"gases",
temp: 70,
tempHigh: 100,
stateHigh: "cloud",
tempLow: 0,
stateLow: "snow_cloud",
state: "gas",
density: 0.5,
ignoreAir: true,
conduct: 0.03
},
"snow_cloud": {
color: "#7e8691",
behavior: [
"XX|XX|XX",
"XX|CH:snow%0.05|M1%2.5 AND BO",
"XX|XX|XX",
],
category:"gases",
temp: -10,
tempHigh: 30,
stateHigh: "rain_cloud",
tempLow: -200,
stateLow: "hail_cloud",
state: "gas",
density: 0.55,
ignoreAir: true,
conduct: 0.01
},
"hail_cloud": {
color: "#7e8691",
behavior: [
"XX|XX|XX",
"XX|CH:hail%0.05|M1%2.5 AND BO",
"XX|XX|XX",
],
category:"gases",
temp: -200,
tempHigh: -160,
stateHigh: "snow_cloud",
state: "gas",
density: 0.6,
ignoreAir: true,
conduct: 0.01
},
"thunder_cloud": {
color: "#494f5b",
behavior: [
"XX|XX|XX",
"XX|CH:lightning%0.001 AND CH:water%0.05|M1%2.5 AND BO",
"XX|XX|XX",
],
tick: function(pixel) {
pixel.temp = 70;
},
category:"gases",
temp: 70,
tempLow: 0,
stateLow: "snow_cloud",
state: "gas",
density: 0.55,
ignoreAir: true,
conduct: 0.03
},
"acid_cloud": {
color: "#637865",
behavior: [
"XX|XX|XX",
"XX|CH:acid%0.05|M1%2.5 AND BO",
"XX|XX|XX",
],
reactions: {
"ash": { elem1:"rain_cloud", elem2:null, chance:0.05 },
"limestone": { elem1:"rain_cloud", elem2:null, chance:0.05 },
"quicklime": { elem1:"rain_cloud", elem2:null, chance:0.05 },
"slaked_lime": { elem1:"rain_cloud", elem2:null, chance:0.05 },
"borax": { elem1:"rain_cloud", elem2:null, chance:0.05 },
"ammonia": { elem1:"rain_cloud", elem2:null, chance:0.05 },
"bleach": { elem1:"rain_cloud", elem2:null, chance:0.05 }
},
category:"gases",
burn: 15,
burnTime: 5,
state: "gas",
density: 0.7,
ignoreAir: true
},
"sandstorm": {
color: "#c2b576",
behavior: [
"XX|XX|XX",
"XX|CH:sand%0.075|M1%2.5 AND BO",
"XX|XX|XX",
],
reactions: {
"sand": { elem2: "sandstorm", chance:0.2, "y":[0,12], "setting":"clouds" },
},
category:"gases",
hidden: true,
state: "gas",
density: 0.8,
ignoreAir: true
},
"pyrocumulus": {
color: "#2e2e2e",
behavior: [
"XX|XX|XX",
"XX|CH:ash%0.075|M1%2.5 AND BO",
"XX|XX|XX",
],
reactions: {
"fireball": { elem1:null, elem2:"fire_cloud", chance:0.25 }
},
category:"gases",
hidden: true,
state: "gas",
density: 0.7,
ignoreAir: true
},
"fire_cloud": {
color: ["#332424","#473431","#473931"],
behavior: [
"XX|XX|XX",
"XX|CH:fireball%0.02|M1%2.5 AND BO",
"XX|XX|XX",
],
reactions: {
"rain_cloud": { elem1: "pyrocumulus", elem2: "pyrocumulus" },
"snow_cloud": { elem1: "pyrocumulus", elem2: "rain_cloud" },
"hail_cloud": { elem1: "pyrocumulus", elem2: "snow_cloud" },
"thunder_cloud": { elem1: "pyrocumulus", elem2: "pyrocumulus" },
"acid_cloud": { elem1: "fire", elem2: "electric" }
},
temp: 500,
tempLow: 100,
stateLow: "pyrocumulus",
category:"gases",
state: "gas",
density: 0.8,
ignoreAir: true,
excludeRandom: true
},
"rad_cloud": {
color: ["#2d7528","#557528"],
behavior: [
"XX|XX|XX",
"XX|CH:fallout,radiation%0.025|M1%2.5 AND BO",
"CR:radiation%0.05|CR:radiation%0.05|CR:radiation%0.05",
],
category:"gases",
hidden: true,
state: "gas",
density: 0.5,
ignoreAir: true
},
"rad_steam": {
color: "#abffe4",
behavior: [
"XX|XX|XX",
"M2%10|XX|M2%10",
"XX|M2%10|XX",
],
reactions: {
"rad_steam": { elem1: null, elem2: "rad_cloud", chance:0.3, "y":[0,15], "setting":"clouds" },
"steam": { elem1: null, elem2: "rad_cloud", chance:0.3, "y":[0,12], "setting":"clouds" },
"cloud": { elem1: "rad_cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"rain_cloud": { elem1: "rad_cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"snow_cloud": { elem1: "rad_cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"hail_cloud": { elem1: "rad_cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"thunder_cloud": { elem1: "rad_cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"pyrocumulus": { elem1: "rad_cloud", chance:0.4, "y":[0,12], "setting":"clouds" },
"rad_cloud": { elem1: "rad_cloud", chance:0.3, "y":[0,12], "setting":"clouds" }
},
tempLow: 10,
stateLow: "fallout",
category: "gases",
hidden: true,
state: "gas",
density: 0.7
},
"color_smoke": {
color: ["#6b2e2e","#6b4f2e","#6b6b2e","#2e6b2e","#2e6b6b","#2e2e6b","#6b2e6b"],
behavior: behaviors.GAS,
category: "gases",
state: "gas",
density: 1.977,
customColor: true
},
"spray_paint": {
color: ["#ff0000","#ff8800","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff"],
behavior: behaviors.GAS,
category: "gases",
state: "gas",
burn: 100,
burnTime: 1,
density: 1250,
customColor: true,
stain: 0.25
},
"led_r": {
behavior: behaviors.WALL,
reactions: {
"light": {"charge1":1},
"liquid_light": {"charge1":1},
},
color: "#660000",
colorOn: "#ff0000",
category: "machines",
tempHigh: 1500,
stateHigh: ["molten_glass","molten_glass","molten_glass","molten_gallium"],
conduct: 1,
breakInto: "glass_shard"
},
"led_g": {
behavior: behaviors.WALL,
reactions: {
"light": {"charge1":1},
"liquid_light": {"charge1":1},
},
color: "#006600",
colorOn: "#00ff00",
category: "machines",
tempHigh: 1500,
stateHigh: ["molten_glass","molten_glass","molten_glass","molten_gallium"],
conduct: 1,
breakInto: "glass_shard"
},
"led_b": {
behavior: behaviors.WALL,
reactions: {
"light": {"charge1":1},
"liquid_light": {"charge1":1},
},
color: "#000066",
colorOn: "#0000ff",
category: "machines",
tempHigh: 1500,
stateHigh: ["molten_glass","molten_glass","molten_glass","molten_gallium"],
conduct: 1,
breakInto: "glass_shard"
},
"sulfur": {
color: ["#e9d74c","#89761b","#ddc56b"],
behavior: behaviors.POWDER,
reactions: {
"hydrogen": { elem2:"stench" }
},
category: "powders",
tempHigh: 115.21,
burn: 25,
burnTime: 207,
fireColor: ["#8180cc","#7f84e6"],
state: "solid",
density: 2070,
alias: "sulphur"
},
"molten_sulfur": {
color: "#831502",
behavior: behaviors.LIQUID,
reactions: {
"iron": { elem1: null, elem2: "pyrite" },
"magnesium": { elem1:null, elem2:"epsom_salt", chance:0.01 },
"molten_magnesium": { elem1:null, elem2:"epsom_salt" },
},
density: 1819,
burn: 25,
burnTime: 507,
tempHigh: 444.6,
viscosity: 8.5,
fireColor: ["#8180cc","#7f84e6"],
burnInto: ["smoke","smoke","smoke","smoke","stench"],
alias: "molten sulphur"
},
"sulfur_gas": {
reactions: {
"molten_magnesium": { elem1:null, elem2:"epsom_salt" },
},
color: "#b0a65d",
burnTime: 10,
density: 2.16,
burnInto: ["smoke","smoke","smoke","smoke","stench"],
},
"copper_sulfate": {
color: ["#4391fd","#004cfe"],
behavior: behaviors.POWDER,
reactions: {
"ant": {elem2:"dead_bug"},
"fly": {elem2:"dead_bug"},
"firefly": {elem2:"dead_bug"},
"stinkbug": {elem2:"dead_bug"},
"bee": {elem2:"dead_bug"},
"termite": {elem2:"dead_bug"},
"plant": {elem2:"dead_plant"},
"grass": {elem2:"dead_plant"},
"algae": {elem2:null},
"mushroom_cap": {elem2:null},
"mushroom_stalk": {elem2:null},
"mushroom_gill": {elem2:null},
"mushroom_spore": {elem2:null},
},
tempHigh: 110,
burn: 10,
burnTime: 1007,
fireColor: ["#91d106","#feff97","#248e01"],
state: "solid",
density: 3600,
hidden: true,
category: "powders"
},
"snake": {
color: "#00bf00",
behavior: [
"XX|XX|XX",
"XX|LB:plant AND RT%5|M1 AND BO:1,2,3",
"XX|XX|XX",
],
rotatable: true,
category: "special",
excludeRandom: true
},
"loopy": {
color: "#eb3474",
behavior: [
"XX|M2|M1",
"XX|RT%20|M2",
"CF|XX|XX",
],
ignore: ["cloner","slow_cloner","clone_powder","floating_cloner","ecloner"],
rotatable: true,
category: "special"
},
"warp": {
color: "#111111",
behavior: [
"XX|M1 AND SW%33|XX",
"M1 AND SW%33|XX|M1 AND SW%33",
"XX|M1 AND SW%33|XX"
],
category:"special",
},
"radiation": {
color: ["#00ff00","#6fff00"],
behavior: [
"XX|M1%0.5 AND HT|XX",
"M1%7 AND HT|DL%3|M1%7 AND HT",
"XX|M1%1 AND HT|XX",
],
reactions: {
"water": { elem2:"rad_steam", chance:0.4 },
"steam": { elem2:"rad_steam", chance:0.4 },
"salt_water": { elem2:"rad_steam", chance:0.4 },
"sugar_water": { elem2:"rad_steam", chance:0.4 },
"dirty_water": { elem2:"rad_steam", chance:0.4 },
"seltzer": { elem2:"rad_steam", chance:0.3 },
"pool_water": { elem2:"rad_steam", chance:0.2 },
"ice": { elem2:"dirty_ice", chance:0.5 },
"salt_ice": { elem2:"dirty_ice", chance:0.5 },
"soda": { elem2:"rad_steam", chance:0.25 },
"juice": { elem2:"rad_steam", chance:0.25 },
"broth": { elem2:"rad_steam", chance:0.3 },
"tea": { elem2:"rad_steam", chance:0.25 },
"coffee": { elem2:"rad_steam", chance:0.25 },
"bubble": { elem2:"rad_steam", chance:0.4 },
"foam": { elem2:"rad_steam", chance:0.4 },
"ice": { elem2:"rad_steam", chance:0.4 },
"rime": { elem2:"rad_steam", chance:0.4 },
"snow": { elem2:"rad_steam", chance:0.4 },
"packed_snow": { elem2:"rad_steam", chance:0.4 },
"slime": { elem2:"rad_steam", chance:0.4 },
"permafrost": { elem1:"rad_steam", elem2:"dirt", chance:0.4 },
"mud": { elem1:"rad_steam", elem2:"dirt", chance:0.4 },
"wet_sand": { elem1:"rad_steam", elem2:"sand", chance:0.4 },
"clay": { elem1:"rad_steam", elem2:"clay_soil", chance:0.4 },
"slaked_lime": { elem1:"rad_steam", elem2:"limestone", chance:0.4 },
"rain_cloud": { elem2:"rad_cloud", chance:0.4 },
"snow_cloud": { elem2:"rad_cloud", chance:0.4 },
"hail_cloud": { elem2:"rad_cloud", chance:0.4 },
"thunder_cloud": { elem2:"rad_cloud", chance:0.4 },
"plant": { elem2:"dead_plant", chance:0.4 },
"evergreen": { elem2:["dead_plant","plant"], chance:0.4 },
"cactus": { elem2:["dead_plant","plant","cactus"], chance:0.4 },
"frozen_plant": { elem2:"dead_plant", chance:0.4 },
"grass": { elem2:["dead_plant","straw","grass_seed","wheat_seed","lettuce","herb"], chance:0.4 },
"herb": { elem2:"dead_plant", chance:0.4 },
"algae": { elem2:["mushroom_spore","lichen","yeast"], chance:0.4 },
"mushroom_spore": { elem2:["lichen","yeast"], chance:0.4 },
"mushroom_cap": { elem2:["lichen","plant"], chance:0.4 },
"mushroom_stalk": { elem2:["lichen","yeast"], chance:0.4 },
"mushroom_gill": { elem2:["lichen","yeast"], chance:0.4 },
"flea": { elem2:["ash","ant","termite"], chance:0.4 },
"ant": { elem2:["ash","flea","termite"], chance:0.4 },
"termite": { elem2:["ash","flea","ant"], chance:0.4 },
"fly": { elem2:["ash","firefly","bee"], chance:0.4 },
"bee": { elem2:["ash","firefly","fly"], chance:0.4 },
"firefly": { elem2:["ash","bee","fly"], chance:0.4 },
"stink_bug": { elem2:"ash", chance:0.4 },
"frog": { elem2:["ash","meat","rotten_meat","cooked_meat","tadpole"], chance:0.4 },
"tadpole": { elem2:["frog","frog","worm",null], chance:0.4 },
"fish": { elem2:["ash","meat","rotten_meat","cooked_meat"], chance:0.4 },
"rat": { elem2:["ash","meat","rotten_meat","cooked_meat","plague"], chance:0.4 },
"bird": { elem2:["ash","meat","rotten_meat","cooked_meat","plague"], chance:0.4 },
"bone": { elem2:["quicklime","quicklime","quicklime","cancer"], chance:0.4 },
"meat": { elem2:["ash","rotten_meat","cooked_meat"], chance:0.4 },
"cheese": { elem2:"rotten_cheese", chance:0.4 },
"rotten_meat": { elem2:["ash","meat","cooked_meat"], chance:0.4 },
"cooked_meat": { elem2:["ash","rotten_meat"], chance:0.4 },
"bamboo": { elem2:["wood","plant","bamboo_plant"], chance:0.4 },
"bamboo_plant": { elem2:["wood","plant","bamboo"], chance:0.4 },
"sapling": { elem2:["wood","plant","tree_branch"], chance:0.4 },
"tree_branch": { elem2:["wood","plant","sapling"], chance:0.4 },
"grass_seed": { elem2:["straw","wheat_seed"], chance:0.4 },
"lichen": { elem2:"algae", chance:0.4 },
"yeast": { elem2:["algae","mushroom_spore","lichen"], chance:0.4 },
"wheat_seed": { elem2:["straw","wheat","grass_seed"], chance:0.4 },
"flower_seed": { elem2:["straw","grass","pistil","petal"], chance:0.4 },
"pistil": { elem2:["straw","grass","flower_seed","petal"], chance:0.4 },
"petal": { elem2:["straw","grass","flower_seed","pistil"], chance:0.4 },
"vine": { elem1:["vine"], chance:0.4 },
"worm": { elem2:"ash", chance:0.4 },
"corn": { elem2:"popcorn", chance:0.4 },
"corn_seed": { elem2:"corn", chance:0.4 },
"potato": { elem2:["potato_seed","potato_seed","potato_seed","potato_seed","potato_seed","potato_seed","explosion"], chance:0.4 },
"potato_seed": { elem2:"potato", chance:0.4 },
"slug": { elem2:"slime", chance:0.4 },
"snail": { elem2:"slime", chance:0.4 },
"cell": { elem2:"cancer", chance:0.4 },
"blood": { elem2:["infection","cancer"], chance:0.4 },
"antibody": { elem2:"cancer", chance:0.4 },
"infection": { elem2:"cancer", chance:0.4 },
"cancer": { elem2:null, chance:0.3 },
"milk": { elem2:["cheese","rotten_cheese","butter","melted_cheese","melted_butter","cream"], chance:0.4 },
"chocolate_milk": { elem2:["cheese","rotten_cheese","butter","melted_cheese","melted_butter","cream"], chance:0.4 },
"fruit_milk": { elem2:["cheese","rotten_cheese","butter","melted_cheese","melted_butter","cream"], chance:0.4 },
"pilk": { elem2:["cheese","rotten_cheese","butter","melted_cheese","melted_butter","cream"], chance:0.4 },
"eggnog": { elem2:["cheese","rotten_cheese","butter","melted_cheese","melted_butter","cream"], chance:0.4 },
"skin": { elem2:["cooked_meat","cancer","ash","skin","hair"], chance:0.4 },
"hair": { elem2:[null,null,"ash"], chance:0.4 },
"tomato": { elem2:["sauce","ketchup"], chance:0.4 },
"sauce": { elem2:["ketchup","rad_steam"], chance:0.4 },
"ketchup": { elem2:["sauce","rad_steam"], chance:0.4 },
"pumpkin": { elem2:"pumpkin_seed", chance:0.4 },
"pumpkin_seed": { elem2:"pumpkin", chance:0.4 },
},
state: "gas",
density: 1.5,
category: "energy"
},
"fallout": {
color: ["#63b85a","#448044","#598044","#7bb85a"],
behavior: [
"XX|CR:radiation%2|XX",
"CR:radiation%2|CH:radiation%0.5|CR:radiation%2",
"M2|M1 AND CR:radiation%2|M2",
],
category:"energy",
hidden: true,
state: "solid",
density: 1490
},
"neutron": {
color: "#a6ffff",
behavior: [
"XX|XX|XX",
"XX|CH:proton%0.25 AND DL%0.25|XX",
"XX|XX|XX",
],
tick: behaviors.BOUNCY,
reactions: {
"uranium": { temp2:100 },
"plant": { elem2:"wood", chance:0.05 },
"gunpowder": { elem2:"dust", chance:0.05 },
"yeast": { elem2:"bread", chance:0.05 },
"firework": { func(pixel1,pixel2){pixel2.burning=true;pixel2.burnStart=pixelTicks}, chance:0.01 },
},
temp: 35,
category: "energy",
state: "gas",
density: 0.00003,
ignoreAir: true
},
"proton": {
color: "#ffa6a6",
behavior: [
"XX|XX|XX",
"XX|DL%0.5|XX",
"XX|XX|XX",
],
behaviorOn: [
"XX|XX|XX",
"XX|CH:hydrogen|XX",
"XX|XX|XX",
],
tick: behaviors.BOUNCY,
reactions: {
"electric": { elem1:null, elem2:"hydrogen", temp2:200 }
},
temp: 40,
category: "energy",
state: "gas",
conduct: 1,
density: 0.00002,
ignoreAir: true
},
"electric": {
color: "#fffba6",
behavior: [
"CL%5|CL%5 AND SH|CL%5",
"CL%5 AND SH|SH%5 AND DL%50|CL%5 AND SH",
"M1%15 AND CL%6|M1%50 AND CL%13 AND SH|M1%15 AND CL%6",
],
charge: 3,
category: "energy",
state: "gas",
density: 2.1,
insulate: true,
ignoreAir: true
},
"uranium": {
color: ["#599e61","#364d3c","#494d4a","#6c8a42","#798d65","#b5e089"],
behavior: [
"XX|CR:radiation%1|XX",
"CR:radiation%1|CH:lead%0.001|CR:radiation%1",
"M2|M1|M2",
],
reactions: {
"neutron": { elem1:"n_explosion", tempMin:500, chance:0.1 }
},
tempHigh: 1132.2,
category: "powders",
state: "solid",
density: 19100,
hardness: 0.6,
conduct: 0.235,
excludeRandom: true
},
"molten_uranium": {
behavior: behaviors.RADMOLTEN,
reactions: {
"neutron": { elem1:"n_explosion", tempMin:200 },
"glass": { elem1:null, elem2:"rad_glass" },
"glass_shard": { elem1:null, elem2:"rad_shard" }
},
density: 17300
},
"diamond": {
color: ["#03fcec","#03c6fc","#b3eeff","#8ab0e6"],
behavior: behaviors.POWDER,
category: "powders",
tempHigh: 900,
stateHigh: "carbon_dioxide",
state: "solid",
density: 3515,
hardness: 0.99
},
"gold_coin": {
color: ["#fff0b5","#ffe680","#c48821","#986a1a","#eca832","#f0bb62"],
behavior: behaviors.POWDER,
tempHigh: 1064,
stateHigh: "molten_gold",
category: "powders",
state: "solid",
density: 19300,
conduct: 0.78,
hardness: 0.2
},
"rust": {
color: ["#ae551c","#bc6e39","#925f49"],
behavior: behaviors.SUPPORT,
tempHigh: 1538,
stateHigh: "molten_iron",
category: "powders",
state: "solid",
density: 5250,
conduct: 0.37,
hardness: 0.3
},
"oxidized_copper": {
color: ["#406555","#42564a","#517364"],
behavior: behaviors.SUPPORT,
reactions: {
"hydrogen": {tempMin:900, elem1:"copper", elem2:"steam"}
},
category: "powders",
hidden: true,
tempHigh: 1085,
stateHigh: "molten_copper",
density: 8960,
conduct: 0.85,
hardness: 0.2,
alias: "copper carbonate"
},
"alga": {
name: "AlGa",
color: ["#bab2ab","#a3ab9d","#a5a4a6","#bcc7b3","#d4c5b8","#cac6cf"],
behavior: behaviors.SUPPORT,
reactions: {
"water": {elem1:["aluminum","gallium"], elem2:"hydrogen", chance:0.01}
},
tempHigh: 345.03,
category: "powders",
state: "solid",
density: 3905,
conduct: 0.39,
hardness: 0.1,
alias: "gallanylidynealumane",
hidden: true
},
"metal_scrap": {
color: ["#b0afb4","#8c8f98","#cbcdcd","#6c6c6a","#fef9ff"],
behavior: behaviors.POWDER,
reactions: {
"rust": { elem1:null, elem2:"thermite", chance:0.1 },
},
tempHigh: 1538,
category: "powders",
density: 2720,
state: "solid",
conduct: 0.43,
hardness: 0.266
},
"glass_shard": {
color: ["#5e807d","#679e99","#596b6e"],
behavior: behaviors.POWDER,
reactions: {
"radiation": { elem1:"rad_shard", chance:0.33 },
"rad_steam": { elem1:"rad_shard", elem2:null, chance:0.33 },
"fallout": { elem1:"rad_shard", elem2:"radiation", chance:0.1 }
},
tempHigh: 1500,
stateHigh: "molten_glass",
category: "powders",
state: "solid",
density: 2500
},
"rad_shard": {
color: ["#648c64","#6aad83","#596e59"],
behavior: behaviors.RADPOWDER,
tempHigh: 1500,
stateHigh: "molten_rad_glass",
category: "powders",
state: "solid",
density: 2500,
hidden: true
},
"brick_rubble": {
color: ["#cb4141","#ab4d4d","#872626"],
behavior: behaviors.POWDER,
category: "powders",
tempHigh: 1540,
stateHigh: "molten_brick",
state: "solid",
density: 1650,
hardness: 0.25,
breakInto: "dust",
hidden: true
},
"baked_clay": {
color: "#b85746",
behavior: behaviors.SUPPORT,
category: "powders",
tempHigh: 1300,
stateHigh: "porcelain",
breakInto: "clay_shard",
state: "solid",
density: 2000,
hardness: 0.3
},
"clay_shard": {
color: ["#b85746","#9c4333","#8a473b"],
behavior: behaviors.POWDER,
category: "powders",
tempHigh: 1300,
stateHigh: "porcelain_shard",
state: "solid",
density: 2000,
hardness: 0.25,
hidden: true
},
"porcelain_shard": {
color: ["#e1e4dd","#c7c7c7","#b8b8b8"],
behavior: behaviors.POWDER,
category: "powders",
state: "solid",
density: 2000,
hardness: 0.325,
hidden: true
},
"feather": {
color: ["#ffffff","#e3e3e3","#d1d1d1"],
behavior: behaviors.LIGHTWEIGHT,
category: "powders",
tempHigh: 400,
stateHigh: ["ash","smoke","smoke","smoke"],
burn:50,
burnTime:20,
burnInto: ["ash","smoke","smoke","smoke"],
state: "solid",
density: 500
},
"confetti": {
color: ["#dc2c37","#edce66","#0dbf62","#0679ea","#7144b2","#d92097"],
behavior: [
"XX|XX|XX",
"XX|FX%0.25|XX",
"M2%25|M1%25|M1%25",
],
reactions: {
"water": { elem1:[null,"cellulose"], chance:0.001 },
"salt_water": { elem1:[null,"cellulose"], chance:0.001 },
"sugar_water": { elem1:[null,"cellulose"], chance:0.001 },
"dirty_water": { elem1:[null,"cellulose"], chance:0.001 },
"seltzer": { elem1:[null,"cellulose"], chance:0.001 },
"pool_water": { elem1:[null,"cellulose"], chance:0.001 },
},
category: "powders",
tempHigh: 248,
stateHigh: ["ash","smoke","smoke","fire"],
burn:15,
burnTime:150,
burnInto: ["ash","smoke","smoke","smoke"],
state: "solid",
density: 1201
},
"glitter": {
color: ["#ace4fb","#d9fcff","#8f6eb2","#fdeafc","#180e1c","#6b2778"],
behavior: behaviors.POWDER,
category: "powders",
tempHigh: 100,
stateHigh: ["fire","fire","dioxin"],
state: "solid",
density: 1450,
burn: 50,
burnTime: 50,
burnInto: ["smoke","smoke","dioxin"]
},
"bead": {
color: ["#ff5e5e","#ffcc5e","#76ff5e","#5ed4ff","#5e61ff","#cf5eff"],
behavior: behaviors.POWDER,
category: "powders",
tempHigh: 185,
stateHigh: "molten_plastic",
burn: 10,
burnTime: 400,
burnInto: "dioxin",
state: "solid",
density: 1052
},
"color_sand": {
color: ["#ff4d4d","#ffac4d","#ffff4d","#4dff4d","#4dffff","#4d4dff","#ff4dff"],
tick: function(pixel) {
behaviors.POWDER(pixel);
if (pixel.start == pixelTicks) {
pixel.color = "hsl(" + (pixel.colorstart||pixel.start) + ",100%,65%)";
if (!pixel.colorstart) {
pixel.colorstart = pixel.start;
}
}
},
tempHigh: 1700,
stateHigh: "molten_stained_glass",
category: "powders",
state: "solid",
density: 1602
},
"borax": {
color: "#ffffff",
behavior: behaviors.POWDER,
reactions: {
"ant": {elem2:"dead_bug"},
"fly": {elem2:"dead_bug"},
"firefly": {elem2:"dead_bug"},
"stinkbug": {elem2:"dead_bug"},
"bee": {elem2:"dead_bug"},
"glue": {elem1:"slime", elem2:"slime", chance:0.1},
},
category: "powders",
burn: 15,
burnTime: 200,
fireColor: ["#34eb67","#5ceb34"],
tempHigh: 743,
state: "solid",
density: 1730,
hidden: true
},
"epsom_salt": {
color: ["#f2f2f2","#d6d6d6"],
behavior: behaviors.POWDER,
category: "powders",
burn: 40,
burnTime: 200,
fireColor: ["#ffffff","#fcf0f0"],
tempHigh: 1124,
state: "solid",
density: 1680,
hidden: true,
alias: "epsom"
},
"potassium_salt": {
color: ["#f2f2f2","#e0e0e0"],
behavior: behaviors.POWDER,
category: "powders",
burn: 40,
burnTime: 200,
fireColor: ["#ff00ee","#ff6bf5"],
tempHigh: 292,
state: "solid",
density: 3980,
hidden: true
},
"caustic_potash": {
color: "#feffe8",
behavior: behaviors.POWDER,
category: "powders",
tempHigh: 410,
state: "solid",
density: 2044,
hidden: true,
alias: "potassium hydroxide"
},
"sodium_acetate": {
color: ["#ededed","#dbdbdb"],
behavior: [
"XX|XX|XX",
"XX|XX|XX",
"M2|M1|M2",
],
tick: function(pixel) {
if ((pixel.foam || Math.random() < 0.25) && isEmpty(pixel.x,pixel.y-1)) {
createPixel("foam",pixel.x,pixel.y-1);
if (pixel.foam) {
pixelMap[pixel.x][pixel.y-1].foam = pixel.foam;
pixel.foam--;
}
}
},
hidden: true,
state: "solid",
density: 1530,
category: "powders",
tempHigh: 881.4
},
"lightning": {
color: "#ffffed",
tick: function(pixel) {
if (!pixel.stage) { // create bolt
var y = pixel.y;
var xoffset = 0;
var last = [pixel.x,pixel.y]
for (var i = 0; i < 100; i++) {
y++;
// randomly go back and forth
if (Math.random() > 0.5) { xoffset++; }
else { xoffset--; }
var x = pixel.x + xoffset;
if (isEmpty(x, y)) {
createPixel("lightning",x,y);
pixelMap[x][y].stage = 1;
pixelMap[x][y].color = pixel.color;
last = [x,y];
}
else if (outOfBounds(x,y) || !elements[pixelMap[x][y].element].isGas) {
//strike
if (Math.random() < 0.01) { // BALL LIGHTNING
pixelMap[last[0]][last[1]].stage = 9;
}
if (!outOfBounds(x,y)) { pixelMap[x][y].temp = 27760 }
explodeAt(x, y, 13, ["plasma","plasma","plasma","electric"]);
break;
}
}
doDefaults(pixel);
deletePixel(pixel.x, pixel.y);
}
else if (pixel.stage === 9) { // BALL LIGHTNING
// move either left or right randomly
if (Math.random() > 0.5) { tryMove(pixel, pixel.x + 1, pixel.y) }
else { tryMove(pixel, pixel.x - 1, pixel.y) }
// create electric in a 3x3 area around pixel
for (var x = pixel.x - 1; x <= pixel.x + 1; x++) {
for (var y = pixel.y - 1; y <= pixel.y + 1; y++) {
if (isEmpty(x, y)) {
createPixel("electric",x,y);
pixelMap[x][y].color = pixel.color;
}
}
}
doDefaults(pixel);
if (pixelTicks - pixel.start >= 250) { deletePixel(pixel.x, pixel.y); }
}
else if (pixelTicks - pixel.start >= 4) {
doDefaults(pixel);
//deletePixel(pixel.x, pixel.y);
changePixel(pixel, "electric")
}
else { doDefaults(pixel); }
},
temp: 27760,
tempLow: -273,
stateLow: ["liquid_light",null],
category: "energy",
state: "gas",
maxSize: 1,
cooldown: defaultCooldown,
density: 1000,
hardness: 1,
excludeRandom: true,
noMix: true
},
"bless": {
color: ["#ffffff","#fffa9c","#00ffff"],
tool: function(pixel) {
if (elements.bless.ignore.indexOf(pixel.element) !== -1) { return; }
if (pixel.burning && !elements[pixel.element].burning) { // stop burning
delete pixel.burning;
delete pixel.burnStart;
}
if (pixel.temp > 100) {
pixel.temp = (pixel.temp+100)/2;
pixelTempCheck(pixel);
if (pixel.del) {return}
}
if (pixel.temp < -200) {
pixel.temp = (pixel.temp-200)/2;
pixelTempCheck(pixel);
if (pixel.del) {return}
}
if (pixel.origColor) {
pixel.color = "rgb("+pixel.origColor.join(",")+")";
delete pixel.origColor;
}
if (pixel.charge) {
delete pixel.charge;
pixel.chargeCD = 16;
}
if (elements.bless.reactions[pixel.element] && Math.random()<0.25) {
var r = elements.bless.reactions[pixel.element];
var elem2 = r.elem2;
if (elem2 !== undefined) {
if (Array.isArray(elem2)) { elem2 = elem2[Math.floor(Math.random()*elem2.length)]; }
if (elem2 === null) { deletePixel(pixel.x,pixel.y) }
else { changePixel(pixel, elem2); }
}
if (r.func) { r.func(pixel,pixel) }
if (r.color2) { pixel.color = pixelColorPick(pixel,r.color2) }
}
},
ignore: ["sun"],
behavior: [
"M2|M1|M2",
"M1|DL%25|M1",
"M2|M1|M2",
],
reactions: {
"cancer": { elem2:null },
"rust": { elem2: "iron" },
"oxidized_copper": { elem2: "copper" },
"blood": { elem2:["antibody",null] },
"blood_ice": { elem2:"antibody_ice" },
"dirty_water": { elem2: "water" },
"plague": { elem2: null },
"virus": { func: function(pixel1,pixel2){pixel2.heal=true} },
"filler": { elem2: "wall" },
"armageddon": { elem2: null },
"lattice": { elem2: "wall" },
"vertical": { elem2: "wall" },
"horizontal": { elem2: "wall" },
"gray_goo": { elem2: "malware" },
"infection": { elem2: ["antibody",null] },
"antibody": { elem2: ["antibody",null] },
"infection_ice": { elem2: "antibody_ice" },
"poison": { elem2: "antidote" },
"poison_gas": { elem2: null },
"poison_ice": { elem2: null },
"rotten_meat": { elem2: "meat" },
"rotten_cheese": { elem2: "cheese" },
"carbon_dioxide": { elem2: "oxygen" },
"pilk": { elem2: "milk" },
"acid": { elem2: "hydrogen" },
"acid_gas": { elem2: "hydrogen" },
"acid_cloud": { elem2: "rain_cloud" },
"fire_cloud": { elem2: "cloud" },
"ash": { elem2: null },
"molten_ash": { elem2: null },
"pyrocumulus": { elem2: null },
"cyanide": { elem2: null },
"cyanide_gas": { elem2: null },
"ammonia": { elem2: null },
"liquid_ammonia": { elem2: null },
"dioxin": { elem2: null },
"stench": { elem2: null },
"liquid_stench": { elem2: null },
"fragrance": { elem2: null },
"chlorine": { elem2: null },
"anesthesia": { elem2: null },
"oil": { elem2: null },
"bleach": { elem2: null },
"soda": { elem2: "seltzer" },
"ink": { elem2: null },
"dye": { elem2: null },
"color_smoke": { elem2: null },
"spray_paint": { elem2: null },
"cancer": { elem2: null },
"rat": { elem2: null },
"flea": { elem2: null },
"termite": { elem2: null },
"smog": { elem2: "cloud" },
"mercury": { elem2: null },
"slime": { elem2: null },
"broth": { elem2: "water" },
"fire": { elem2: "bless" },
"plasma": { elem2: "bless" },
"grenade": { elem2: "metal_scrap" },
"flashbang": { elem2: "metal_scrap" },
"smoke_grenade": { elem2: "metal_scrap" },
"greek_fire": { elem2: "smoke" },
"nitro": { elem2: null },
"smoke": { elem2: null },
"lightning": { elem2: null },
"electric": { elem2: null },
"positron": { elem2: null },
"antimatter": { elem2: null },
"neutron": { elem2: null },
"proton": { elem2: null },
"radiation": { elem2: "flash" },
"uranium": { elem2: "rock" },
"molten_uranium": { elem2: "magma" },
"magma": { elem2: "rock" },
"mercury": { elem2: null },
"mercury_gas": { elem2: null },
"solid_mercury": { elem2: null },
"ice_nine": { elem2: "ice" },
"strange_matter": { elem2: "neutron" },
"frozen_frog": { elem2: "frog" },
"frozen_worm": { elem2: "worm" },
"molten_thermite": { elem2: "rock" },
"rad_glass": { elem2: "glass" },
"rad_shard": { elem2: "glass_shard" },
"rad_steam": { elem2: "steam" },
"fallout": { elem2: null },
"rad_cloud": { elem2: "rain_cloud" },
"fireball": { elem2: "ball" },
"bone_marrow": { elem2: "bone" },
"fly": { elem2: null },
"dead_bug": { elem2: null },
"dead_plant": { elem2: "plant" },
"wood": { func:function(pixel1,pixel2) {if(pixel2.wc){changePixel(pixel2,"tree_branch")}} },
"slag": { elem2: "rock" },
"molten_slag": { elem2: "magma" },
"laser": { elem2: "light" },
"light": { elem2: "flash" },
"torch": { elem2: "wood" },
"explosion": { elem2: null },
"n_explosion": { elem2: null },
"supernova": { elem2: null },
"pop": { elem2: null },
"ember": { elem2: null },
"fw_ember": { elem2: null },
"pollen": { elem2: null },
"lead": { elem2: "gold" },
"molten_lead": { elem2: "molten_gold" },
"dirt": { elem1: "grass", oneway:true },
"static": { elem2: "rainbow" },
},
temp:20,
state: "gas",
density: 0.001,
canPlace: true,
category: "energy",
stain: -0.5
},
"god_ray": {
color: ["#ffffff","#ffee57"],
tick: function(pixel) {
var x = pixel.x;
for (var y = pixel.y+1; y < height; y++) {
if (outOfBounds(x, y)) {
break;
}
if (isEmpty(x, y)) {
if (Math.random() > 0.1) { continue }
createPixel("flash", x, y);
}
else {
if (elements[pixelMap[x][y].element].id === elements.flash.id) { continue }
if (elements[pixelMap[x][y].element].id === elements.god_ray.id) { break }
if (!elements[pixelMap[x][y].element].isGas && isEmpty(x, y-1)) {
createPixel("bless", x, y-1);
}
if (Math.random() > 0.1) { continue }
elements.bless.tool(pixelMap[x][y])
}
}
deletePixel(pixel.x, pixel.y);
},
category: "energy",
state: "gas",
density: 1,
excludeRandom: true,
noMix: true
},
"heat_ray": {
color: ["#ff0000","#ff5e00"],
tick: function(pixel) {
var x = pixel.x;
for (var y = pixel.y; y < height; y++) {
if (outOfBounds(x, y)) {
break;
}
if (isEmpty(x, y)) {
if (Math.random() > 0.05) { continue }
createPixel("flash", x, y);
pixelMap[x][y].color = "#ff0000";
pixelMap[x][y].temp = 3500;
}
else {
if (elements[pixelMap[x][y].element].isGas) { continue }
if (elements[pixelMap[x][y].element].id === elements.heat_ray.id) { break }
pixelMap[x][y].temp += 100;
pixelTempCheck(pixelMap[x][y]);
break;
}
}
deletePixel(pixel.x, pixel.y);
},
temp: 3500,
category: "energy",
state: "gas",
density: 1,
excludeRandom: true,
noMix: true
},
"explosion": {
color: ["#ffb48f","#ffd991","#ffad91"],
behavior: [
"XX|XX|XX",
"XX|EX:10|XX",
"XX|XX|XX",
],
temp: 300,
category: "energy",
state: "gas",
density: 1000,
excludeRandom: true,
noMix: true
},
"n_explosion": {
color: ["#c3ff91","#8fffaf","#8fffda"],
behavior: [
"XX|XX|XX",
"XX|EX:40>plasma,plasma,plasma,plasma,radiation,rad_steam|XX",
"XX|XX|XX",
],
temp: 100000000,
category: "energy",
state: "gas",
density: 1000,
excludeRandom: true,
hidden: true,
alias: "nuclear explosion",
noMix: true
},
"supernova": {
color: ["#ebf8ff","#dbf3ff","#b8e7ff"],
behavior: [
"XX|XX|XX",
"XX|EX:80>plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,molten_iron,molten_uranium,molten_lead,oxygen,molten_sodium,sulfur_gas,neon,chlorine,molten_calcium,molten_nickel,molten_copper,molten_zinc,gallium_gas,molten_potassium AND CH:void|XX",
"XX|XX|XX",
],
temp: 99999999700,
category: "energy",
state: "gas",
density: 1000,
hardness: 1,
hidden: true,
excludeRandom: true,
maxSize: 1,
noMix: true
},
"pop": {
color: ["#ffce8f","#ffe091","#ffe791"],
behavior: [
"XX|XX|XX",
"XX|EX:3|XX",
"XX|XX|XX",
],
category: "energy",
state: "gas",
density: 1000,
excludeRandom: true,
hidden: true,
noMix: true
},
"cook": {
color: ["#5c3322","#2b1107","#5c3322","#5c3322","#2b1107","#5c3322"],
tool: function(pixel) {
if (!shiftDown) {
pixel.temp += 0.5;
pixelTempCheck(pixel);
}
else {
pixel.temp += 1;
pixelTempCheck(pixel);
}
},
category: "energy",
excludeRandom: true
},
"incinerate": {
color: ["#e600ff","#d984d8","#ff00e1"],
tool: function(pixel) {
pixel.temp += 10000;
if (!pixel.burning && elements[pixel.element].burn) {
pixel.burning = true;
pixel.burnStart = pixelTicks;
}
pixelTempCheck(pixel);
},
category: "energy",
excludeRandom: true
},
"room_temp": {
color: "#b1c96d",
tool: function(pixel) {
pixel.temp = (pixel.temp+20)/2;
pixelTempCheck(pixel);
},
category: "energy",
excludeRandom: true
},
"positron": {
color: "#a6bfff",
behavior: [
"M1%15 AND CL%6|M1%50 AND CL%13|M1%15 AND CL%6",
"CL%5|DL%50|CL%5",
"CL%5|CL%5|CL%5",
],
reactions: {
"electric": { elem1:"light", elem2:"explosion" }
},
category: "energy",
state: "gas",
density: 2.1,
insulate: true,
hidden: true,
ignoreAir: true
},
"tnt": {
color: "#c92a2a",
behavior: behaviors.WALL,
behaviorOn: [
"XX|XX|XX",
"XX|EX:10|XX",
"XX|XX|XX",
],
conduct: 1,
category: "weapons",
burn: 100,
burnTime: 1,
burnInto: "explosion",
tempHigh: 600,
stateHigh: "explosion",
state: "solid",
density: 1630,
excludeRandom: true,
alias: "trinitrotoluene"
},
"c4": {
name: "C-4",
color: ["#d7c1a1","#c8a77c"],
behavior: behaviors.STURDYPOWDER,
behaviorOn: [
"XX|XX|XX",
"XX|EX:10|XX",
"XX|M1|XX",
],
conduct: 1,
category: "weapons",
burn: 5,
burnTime: 800,
burnInto: ["fire","fire","poison_gas"],
breakInto: "explosion",
state: "solid",
density: 1630,
excludeRandom: true
},
"grenade": {
color: "#5e5c57",
behavior: [
"XX|EX:6>metal_scrap,fire,fire,fire%1|XX",
"XX|XX|XX",
"M2|M1 AND EX:6>metal_scrap,fire,fire,fire%1|M2",
],
behaviorOn: [
"XX|XX|XX",
"XX|EX:6>metal_scrap,fire,fire,fire%1|XX",
"XX|XX|XX",
],
category: "weapons",
state: "solid",
density: 1300,
tempHigh: 1455.5,
stateHigh: "molten_steel",
excludeRandom: true,
conduct: 1,
cooldown: defaultCooldown,
nocheer: true
},
"dynamite": {
color: ["#de5050","#c92a2a","#a61919"],
behavior: behaviors.POWDER,
behaviorOn: [
"XX|XX|XX",
"XX|CH:explosion|XX",
"XX|XX|XX",
],
conduct: 1,
category: "weapons",
tempHigh: 600,
stateHigh: "explosion",
state: "solid",
density: 1300,
breakInto: "explosion",
excludeRandom: true
},
"gunpowder": {
color: ["#929980","#757767","#423d43"],
behavior: behaviors.POWDER,
category: "weapons",
burn: 100,
burnTime: 1,
burnInto: ["explosion","pop","pop"],
tempHigh: 600,
stateHigh: "explosion",
state: "solid",
density: 1700,
excludeRandom: true
},
"ember": {
color: ["#ffe985","#ffd885","#ffc285"],
behavior: [
"XX|M1|M1",
"XX|XX|XX",
"XX|XX|XX",
],
flippableX: true,
category: "energy",
temp: 300,
tempLow: 0,
stateLow: "ash",
burn: 10,
burnTime: 10,
burnInto: "ash",
burning: true,
state: "gas",
density: 700,
hidden: true
},
"firework": {
color: "#c44f45",
tick: function(pixel) {
if ((pixel.temp > 1000 || pixel.charge) && !pixel.burning) {
pixel.burning = true;
pixel.burnStart = pixelTicks;
}
if (pixel.burning) {
if (!tryMove(pixel, pixel.x, pixel.y-1)) {
// tryMove again to the top left or top right
tryMove(pixel, pixel.x+(Math.random() < 0.5 ? -1 : 1), pixel.y-1);
}
if (pixelTicks-pixel.burnStart > 50 && Math.random() < 0.1) {
explodeAt(pixel.x, pixel.y, 10, "fw_ember");
}
}
else {
if (!tryMove(pixel, pixel.x, pixel.y+1)) {
// tryMove again to the bottom left or bottom right
tryMove(pixel, pixel.x+(Math.random() < 0.5 ? -1 : 1), pixel.y+1);
}
}
doDefaults(pixel);
},
burn: 90,
burnTime: 100,
density: 2000,
conduct: 1,
state: "solid",
category: "weapons"
},
"fw_ember": {
color: ["#ff7a70","#ff9b70","#ffe270","#94ff70","#00ffff","#9b70ff","#ffa8d2"],
behavior: [
"XX|XX|XX",
"XX|DL%25|M2",
"XX|M2|M1",
],
burning: true,
burnInto: "ash",
fireElement: "carbon_dioxide",
rotatable: true,
temp: 649,
tempLow: 0,
stateLow: "carbon_dioxide",
category: "energy",
hidden: true,
state: "gas",
density: 700,
alias: "firework ember"
},
"nuke": {
color: "#534636",
behavior: [
"XX|XX|XX",
"XX|XX|XX",
"M2|M1 AND EX:60>plasma,plasma,plasma,plasma,radiation,rad_steam|M2",
],
category: "weapons",
state: "solid",
density: 1500,
excludeRandom: true,
cooldown: defaultCooldown
},
"h_bomb": {
color: "#533636",
behavior: [
"XX|XX|XX",
"XX|XX|XX",
"M2|M1 AND EX:90>plasma,plasma,plasma,plasma,fire|M2",
],
category: "weapons",
state: "solid",
density: 1600,
excludeRandom: true,
alias: "hydrogen bomb",
cooldown: defaultCooldown
},
"dirty_bomb": {
color: "#415336",
behavior: [
"XX|XX|XX",
"XX|XX|XX",
"M2|M1 AND EX:40>radiation,radiation,radiation,rad_steam|M2",
],
category: "weapons",
state: "solid",
density: 1400,
excludeRandom: true,
cooldown: defaultCooldown
},
"emp_bomb": {
color: "#418273",
tick: function(pixel) {
if (pixel.start===pixelTicks) {return}
if (!tryMove(pixel,pixel.x,pixel.y+1)) {
if (outOfBounds(pixel.x,pixel.y+1) || (pixelMap[pixel.x][pixel.y+1].element!=="emp_bomb" && elements[pixelMap[pixel.x][pixel.y+1].element].state!=="gas")) {
for (i = 0; i < currentPixels.length; i++) {
var newPixel = currentPixels[i];
if (newPixel.charge) {
delete newPixel.charge;
newPixel.chargeCD = 16;
}
if (elements[newPixel.element].id === elements.gray_goo.id) {
changePixel(newPixel,"flash")
}
}
explodeAt(pixel.x,pixel.y+1,20,"flash");
}
}
doDefaults(pixel);
},
category: "weapons",
state: "solid",
density: 1400,
excludeRandom: true,
alias: "electromagnetic pulse bomb",
cooldown: defaultCooldown
},
"nitro": {
color: "#47c900",
behavior: behaviors.LIQUID,
behaviorOn: [
"XX|XX|XX",
"XX|EX:10|XX",
"XX|XX|XX",
],
reactions: {
"clay": { elem1:"dynamite", elem2:"dynamite" },
"tnt": { elem1:"dynamite", elem2:"dynamite" },
},
conduct: 1,
category: "weapons",
tempHigh: 600,
stateHigh: "fire",
tempLow: 14,
stateLowName: "frozen_nitro",
burn: 100,
burnTime: 1,
burnInto: "explosion",
breakInto: "explosion",
viscosity: 36,
state: "liquid",
density: 1600,
excludeRandom: true,
alias: "nitroglycerin"
},
"greek_fire": {
color: ["#4a3923","#594933","#78654a"],
behavior: behaviors.LIQUID,
reactions: {
"water": { func: function(pixel){if (!pixel.burning) { pixel.burning=true; pixel.burnStart=pixelTick }}},
"salt_water": { func: function(pixel){if (!pixel.burning) { pixel.burning=true; pixel.burnStart=pixelTick }}},
"sugar_water": { func: function(pixel){if (!pixel.burning) { pixel.burning=true; pixel.burnStart=pixelTick }}},
"dirty_water": { func: function(pixel){if (!pixel.burning) { pixel.burning=true; pixel.burnStart=pixelTick }}},
"pool_water": { func: function(pixel){if (!pixel.burning) { pixel.burning=true; pixel.burnStart=pixelTick }}},
"seltzer": { func: function(pixel){if (!pixel.burning) { pixel.burning=true; pixel.burnStart=pixelTick }}},
"sand": { elem1:null, chance:0.05 },
"wet_sand": { elem1:null, chance:0.05 },
"vinegar": { elem1:null, chance:0.05 },
"dirt": { elem1: null, elem2: "mud" },
"sand": { elem1: null, elem2: "wet_sand" },
"clay_soil": { elem1: null, elem2: "clay" },
"plasma": { elem1:"fire" },
},
category: "weapons",
tempHigh: 4000,
stateHigh: "fire",
burn: 100,
burnTime: 1500,
burnInto: "fire",
insulate: true,
viscosity: 2,
state: "liquid",
density: 498.5,
excludeRandom: true
},
"fireball": {
color: ["#782828","#783b28","#784b28"],
behavior: [
"XX|CR:fire%25|XX",
"XX|CC:782828,783b28,784b28%25|XX",
"M2|M1 AND EX:8|M2",
],
reactions: {
"water": { elem1:"rock", elem2:"steam" }
},
category: "weapons",
temp:600,
tempLow: -100,
stateLow: "rock",
burning: true,
burnInto: ["rock","rock","steam"],
burnTime: 170,
burn: 100,
state: "solid",
density: 1600,
excludeRandom: true,
cooldown: defaultCooldown
},
"rocket": {
color: "#ff6f47",
tick: function(pixel) {
if (pixel.clone) {
tryMove(pixel,pixel.x,pixel.y-1,pixel.clone);
tryMove(pixel,pixel.x + (Math.random() < 0.5 ? -1 : 1),pixel.y);
if (pixelTicks-pixel.burnStart > 20 && Math.random() < 0.025) {
deletePixel(pixel.x,pixel.y);
explodeAt(pixel.x,pixel.y,10,"smoke")
return
}
}
else if (!tryMove(pixel,pixel.x,pixel.y+1)) {
if (!outOfBounds(pixel.x,pixel.y+1)) {
if (pixelMap[pixel.x][pixel.y+1].clone) { pixel.clone = pixelMap[pixel.x][pixel.y+1].clone }
else if (pixelMap[pixel.x][pixel.y+1].element === "rocket") {
behaviors.POWDER(pixel);
}
else { pixel.clone = pixelMap[pixel.x][pixel.y+1].element }
}
else {
pixel.clone = "smoke"
}
pixel.burnStart = pixelTicks
}
doDefaults(pixel)
},
category: "weapons",
state: "solid",
density: 7300,
cooldown: defaultCooldown
},
"antibomb": {
color: "#adb3be",
tick: function(pixel) {
doDefaults(pixel)
if (!tryMove(pixel,pixel.x,pixel.y+1)) {
if (!outOfBounds(pixel.x,pixel.y+1)) {
var elem = pixelMap[pixel.x][pixel.y+1].element;
if (elements[elem].isGas) { return }
}
else {
var elem = "smoke";
}
if (elem !== "antibomb") {
explodeAt(pixel.x,pixel.y,8,elem)
}
}
},
category: "weapons",
state: "solid",
density: 4300,
darkText: true,
cooldown: defaultCooldown
},
"cold_bomb": {
color: "#43646e",
behavior: [
"XX|EX:10>cold_fire|XX",
"XX|XX|XX",
"M2|M1 AND EX:10>cold_fire|M2",
],
category: "weapons",
state: "solid",
density: 1300,
tempHigh: 1455.5,
stateHigh: "molten_steel",
excludeRandom: true,
cooldown: defaultCooldown
},
"hot_bomb": {
color: "#6c436e",
behavior: [
"XX|HT:20000 AND EX:15>plasma|XX",
"XX|XX|XX",
"M2|M1 AND HT:20000 AND EX:15>plasma|M2",
],
category: "weapons",
state: "solid",
density: 1300,
excludeRandom: true,
cooldown: defaultCooldown
},
"antimatter_bomb": {
color: "#6e4343",
behavior: [
"XX|EX:20>antimatter|XX",
"XX|XX|XX",
"M2|M1 AND EX:20>antimatter|M2",
],
category: "weapons",
state: "solid",
density: 1300,
tempHigh: 10455.5,
stateHigh: "molten_steel",
excludeRandom: true,
cooldown: defaultCooldown
},
"party_popper": {
color: ["#dc2c37","#edce66","#0dbf62","#0679ea","#7144b2","#d92097"],
behavior: [
"XX|EX:15>confetti,flash,flash,smoke|XX",
"XX|XX|XX",
"M2|M1 AND EX:15>confetti,flash,flash,smoke|M2",
],
category: "weapons",
state: "solid",
density: 1300,
excludeRandom: true,
cooldown: defaultCooldown
},
"flashbang": {
color: "#65665c",
behavior: [
"XX|EX:20>flash%1|XX",
"XX|XX|XX",
"M2|M1 AND EX:20>flash%1|M2",
],
category: "weapons",
state: "solid",
density: 1300,
tempHigh: 1455.5,
stateHigh: "molten_steel",
excludeRandom: true,
cooldown: defaultCooldown
},
"flash": {
color: "#fffdcf",
tick: function(pixel) {
if (Math.random() < 0.75 && pixelTicks - pixel.start > 1) {
deletePixel(pixel.x, pixel.y)
}
doHeat(pixel);
},
reactions: {
"blood": { elem1:"pointer" },
"molten_stained_glass": { elem1:"rainbow" },
"electric": { elem1:"pointer" },
},
category: "energy",
temp: 40,
tempLow: -270,
stateLow: ["liquid_light",null],
state: "gas",
density: 1,
hidden: true,
noMix: true
},
"smoke_grenade": {
color: "#65665c",
behavior: [
"XX|CR:smoke|XX",
"XX|EX:4>smoke%1|XX",
"M2|M1|M2",
],
category: "weapons",
state: "solid",
density: 7300,
conduct: 0.73,
tempHigh: 1455.5,
stateHigh: "molten_steel",
excludeRandom: true,
cooldown: defaultCooldown,
nocheer: true
},
"landmine": {
color: "#856c7d",
behavior: [
"XX|EX:20|XX",
"XX|XX|XX",
"XX|M1|XX",
],
category: "weapons",
state: "solid",
density: 1300,
tempHigh: 1455.5,
stateHigh: "molten_steel",
excludeRandom: true,
cooldown: defaultCooldown,
nocheer: true
},
"tornado": {
color: ["#b8b8b8","#979797","#787878"],
tick: function(pixel) {
doHeat(pixel);
if (pixel.stage) {
if (pixel.stage === -1) {
if (!isEmpty(pixel.x,pixel.y+1,true)) {
var pixel2 = pixelMap[pixel.x][pixel.y+1];
if (pixel2.element !== "tornado" && elements[pixel2.element].movable) {
deletePixel(pixel.x,pixel.y);
tryMove(pixel2,pixel2.x,pixel2.y-1);
return;
}
}
if (Math.random() < 0.1) {
deletePixel(pixel.x,pixel.y);
return;
}
return;
}
for (var y = 0; y <= pixel.stage; y++) {
for (var x = -y-0.5; x <= y+0.5; x++) {
var nx = Math.round(pixel.x+x/2);
var ny = Math.round(pixel.y-y);
if (isEmpty(nx,ny)) {
createPixel("tornado",nx,ny);
pixelMap[nx][ny].stage = -1;
}
else if (!outOfBounds(nx,ny)) {
// try to break and then move it up
var p = pixelMap[nx][ny];
if (elements[p.element].breakInto && Math.random() < (elements[p.element].hardness || 1) * 0.1) {
breakPixel(p);
}
if (p.del || elements[p.element].id === elements.tornado.id || !elements[p.element].movable) { continue; }
tryMove(p,p.x,p.y-1);
}
}
}
for (var y = 0; y <= Math.min(4,pixel.stage); y++) {
for (var x = -pixel.stage; x <= pixel.stage; x++) {
var nx = Math.round(pixel.x+x/2);
var ny = pixel.y-y;
if (!isEmpty(nx,ny,true) && Math.random() < 0.3) {
var p = pixelMap[nx][ny];
if (elements[p.element].breakInto && Math.random() < (elements[p.element].hardness || 1) * 0.1) {
breakPixel(p);
}
if (p.del || elements[p.element].id === elements.tornado.id || !elements[p.element].movable) { continue; }
tryMove(p,p.x,p.y-1);
}
}
}
if (pixel.stage < pixel.mag) {
pixel.stage++;
}
}
else {
pixel.mag = Math.floor(Math.random() * 7) + 15
pixel.stage = 1;
pixel.dir = Math.random() < 0.5 ? -1 : 1;
}
tryMove(pixel,pixel.x,pixel.y+1);
if (Math.random() < 0.1 && !tryMove(pixel,pixel.x+pixel.dir,pixel.y)) {
tryMove(pixel,pixel.x+pixel.dir,pixel.y-1)
if (Math.random() < 0.2) {
pixel.dir = -pixel.dir;
}
}
if (pixelTicks - pixel.start > 400 && Math.random() < 0.2) {
pixel.stage -= 2;
pixel.mag -= 1;
if (pixel.stage < 2) {
deletePixel(pixel.x,pixel.y);
}
}
},
category: "weapons",
state: "gas",
density: 1.23,
maxSize: 1,
cooldown: defaultCooldown,
excludeRandom: true,
},
"earthquake": {
color: ["#bda791","#997756","#613d19"],
tick: function(pixel) {
if (pixel.stage) {
var coords = circleCoords(pixel.x,pixel.y,pixel.stage);
if (pixel.stage >= pixel.mag) {
deletePixel(pixel.x,pixel.y);
return;
}
coords.forEach(function(coord){
var x = coord.x;
var y = coord.y;
if (!isEmpty(x,y,true)) {
var p = pixelMap[x][y];
if (p.element === "earthquake") { return }
if (elements[p.element].breakInto) {
if (Math.random() < (elements[p.element].hardness || 1) * 0.25) {
breakPixel(p);
}
}
if (p.del || !elements[p.element].movable) { return }
tryMove(p,p.x,p.y-1);
}
})
pixel.stage++;
}
else if (!tryMove(pixel,pixel.x,pixel.y+1)) {
// random 10 to 20
pixel.mag = Math.floor(Math.random() * 10) + 20;
pixel.stage = 1;
}
},
category: "weapons",
state: "solid",
density: 100000000,
maxSize: 1,
cooldown: defaultCooldown,
excludeRandom: true,
},
"tsunami": {
color: ["#91b9bd","#566f99","#192f61"],
tick: function(pixel) {
if (pixel.stage) {
var coords = circleCoords(pixel.x,pixel.y,pixel.stage);
var coords = rectCoords(Math.floor(pixel.x-pixel.stage/2),pixel.y-pixel.stage,Math.floor(pixel.x+pixel.stage/2),pixel.y);
if (pixel.stage >= pixel.mag) {
deletePixel(pixel.x,pixel.y);
return;
}
coords.forEach(function(coord){
var x = coord.x;
var y = coord.y;
if (!isEmpty(x,y,true)) {
var p = pixelMap[x][y];
if (p.element === "tsunami") { return }
if (elements[p.element].breakInto) {
if (Math.random() < (elements[p.element].hardness || 1) * 0.1) {
breakPixel(p);
}
}
if (!elements[p.element].movable) { return }
if (!p.del && Math.random() < 0.1) { tryMove(p,p.x,p.y-1); }
}
else if (isEmpty(x,y)) {
createPixel(pixel.clone,x,y);
}
})
pixel.stage++;
}
else if (!tryMove(pixel,pixel.x,pixel.y+1)) {
if (!isEmpty(pixel.x,pixel.y+1,true)) {
var elem = pixelMap[pixel.x][pixel.y+1].element;
if (elem === "tsunami") { return }
if (elements[elem].state !== "liquid") { pixel.clone = "water"; }
else { pixel.clone = elem; }
}
else {
pixel.clone = "water";
}
// random 10 to 20
pixel.mag = Math.floor(Math.random() * 10) + 20;
pixel.stage = 1;
}
},
category: "weapons",
state: "liquid",
maxSize: 1,
density: 997,
cooldown: defaultCooldown,
excludeRandom: true,
},
"blaster": {
color: ["#ff0000","#ff4d00","#ff7700"],
tick: function(pixel) {
for (var i = 0; i < 3; i++) {
var skip = false;
if (!isEmpty(pixel.x,pixel.y+1,true)) {
var p = pixelMap[pixel.x][pixel.y+1];
if (p.element === "blaster") { skip = true; }
if (Math.random() < 0.9 && elements[p.element].hardness !== 1) {
deletePixel(p.x,p.y);
}
}
if (!tryMove(pixel,pixel.x,pixel.y+1,["flash","heat_ray","electric"]) && !skip) {
explodeAt(pixel.x,pixel.y,20,"plasma");
var coords = circleCoords(pixel.x,pixel.y,15);
coords.forEach(function(coord){
var x = coord.x;
var y = coord.y;
if (!isEmpty(x,y,true)) {
pixelMap[x][y].temp += 10000;
pixelTempCheck(pixelMap[x][y]);
}
})
deletePixel(pixel.x,pixel.y);
return;
}
}
},
category: "weapons",
state: "solid",
density: 100000000,
temp: 10000,
hardness: 1,
maxSize: 3,
cooldown: defaultCooldown,
excludeRandom: true,
},
"armageddon": {
color: "#a62900",
behavior: [
"XX|XX|XX",
"XX|EX:10>armageddon,fire,fire,fire,fire,fire,fire,fire,fire,fire,fire,fire,fire%25 AND DL%10|XX",
"XX|XX|XX",
],
category: "weapons",
state: "solid",
density: 1300,
hidden: true,
excludeRandom: true,
maxSize: 1,
cooldown: defaultCooldown
},
"tesla_coil": {
color: "#725c38",
behavior: behaviors.WALL,
behaviorOn: [
"XX|CR:plasma|XX",
"CR:plasma|XX|CR:plasma",
"XX|CR:plasma|XX",
],
category: "machines",
conduct: 1,
insulate: true,
temp: 7065
},
"light_bulb": {
color: "#a8a897",
behavior: behaviors.WALL,
behaviorOn: [
"XX|CR:light|XX",
"CR:light|XX|CR:light",
"XX|CR:light|XX",
],
colorOn: "#ebebc3",
category: "machines",
tempHigh: 1500,
stateHigh: ["molten_glass","molten_glass","molten_copper"],
conduct: 1,
breakInto: "glass_shard"
},
"shocker": {
color: "#78784c",
behavior: behaviors.WALL,
behaviorOn: [
"XX|CR:electric AND SH|XX",
"CR:electric AND SH|XX|CR:electric AND SH",
"XX|CR:electric AND SH|XX",
],
colorOn: "#ffff59",
category: "machines",
conduct: 1
},
"pressure_plate": {
color: "#8a8a84",
tick: function(pixel) {
if (!isEmpty(pixel.x, pixel.y-1, true)){
if (pixelMap[pixel.x][pixel.y-1].element != "pressure_plate" || pixelMap[pixel.x][pixel.y-1].on) {
pixel.on = true;
var coordsToShock = [
[pixel.x, pixel.y+1],
[pixel.x+1, pixel.y],
[pixel.x-1, pixel.y],
]
for (var i = 0; i < coordsToShock.length; i++) {
var x = coordsToShock[i][0];
var y = coordsToShock[i][1];
if (!isEmpty(x,y,true)) {
var newpixel = pixelMap[x][y];
if (elements[newpixel.element].conduct) {
newpixel.charge = 1;
}
}
}
}
}
else if (pixel.on) {
pixel.on = false;
}
tryMove(pixel, pixel.x, pixel.y+1);
},
category: "machines"
},
"primordial_soup": {
color: ["#501f24","#6d2e1d"],
behavior: [
"XX|CR:foam%2|XX",
"M2|CH:algae,cell,mushroom_spore,lichen,yeast,antibody,cellulose,seltzer,oxygen%0.005|M2",
"M1|M1|M1",
],
behaviorOn: [
"XX|CR:foam%25|XX",
"M2|CH:algae,cell,mushroom_spore,lichen,yeast,antibody,cellulose,seltzer,oxygen%5|M2",
"M1|M1|M1",
],
reactions: {
"cancer": { elem1:"dirty_water" },
"cyanide": { elem1:"dirty_water" },
"cyanide_gas": { elem1:"dirty_water" },
"infection": { elem1:"dirty_water" },
"blood": { elem2:"antibody" },
"plague": { elem1:"dirty_water" },
"bleach": { elem1:"dirty_water" },
"poison": { elem1:"dirty_water" },
"soap": { elem1:"water" },
"alcohol": { elem1:"water" },
"mercury": { elem1:"dirty_water" },
"ammonia": { elem1:["algae","cell","mushroom_spore","lichen","yeast","antibody"], chance:0.05 },
"radiation": { elem1:["algae","cell","mushroom_spore","lichen","yeast","antibody"], chance:0.15 },
"uranium": { elem1:["algae","cell","mushroom_spore","lichen","yeast","antibody"], chance:0.001 },
"light": { elem1:["algae","cell","mushroom_spore","lichen","yeast","antibody"], chance:0.5 },
"carbon_dioxide": { elem2:"oxygen" },
"milk": { elem2:"yogurt" },
"dirt": { elem2:"mud", chance:0.2 },
"sand": { elem2:"wet_sand", chance:0.2 },
"clay_soil": { elem2:"clay", chance:0.2 },
"rock": { elem2:"wet_sand", chance:0.001 },
"copper": { elem1:null, elem2:"oxidized_copper", chance:0.05 },
"bronze": { elem1:null, elem2:"oxidized_copper", chance:0.025 },
"iron": { elem1:null, elem2:"rust", chance:0.025 },
"steel": { elem1:null, elem2:"rust", chance:0.02 },
},
category: "life",
temp: 30,
tempHigh: 100,
stateHigh: "steam",
conduct: 0.05,
state: "liquid",
density: 955,
stain: -0.1
},
"molten_slag": {
ignore: ["salt","plastic","sulfur","epsom_salt","potassium_salt","borax","solder","ash","dirt","tuff"]
},
"molten_dirt": {
stateLow: ["mudstone","mudstone","mudstone","mudstone","mudstone","mudstone","mudstone","mudstone","mudstone","mudstone","mudstone","mudstone","rock"]
},
"debug": {
color: ["#b150d4","#d1b74f"],
tool: function(pixel) {
mouseIsDown = false;
shiftDown = false;
var output = pixel.element.toUpperCase()+" at x"+pixel.x+", y"+pixel.y+", tick"+pixelTicks+"\n";
for (var i in pixel) {
if (i !== "x" && i !== "y" && i !== "element") {
output += " " + i + ": " + pixel[i] + "\n";
}
}
console.log(output);
console.log(JSON.stringify(pixel));
alert(output);
lastDebug = pixelTicks;
},
maxSize: 1,
category: "special"
},
"prop": {
color: ["#d46f50","#d4aa50"],
onSelect: function(){
var answer1 = prompt("Warning - This tool may break Sandboxels if used incorrectly. Avoid using if you don't understand.\n\nEnter a pixel attribute to modify:",(currentProp||undefined));
if (!answer1) { selectElement("unknown"); return }
var answer2 = prompt("Now, enter a value for "+answer1+":",(currentPropValue||undefined));
if (!answer2) { selectElement("unknown"); return }
var valueL = answer2.toLowerCase();
if (valueL === "true") { answer2 = true }
else if (valueL === "false") { answer2 = false }
else if (valueL === "null") { answer2 = null }
else if (valueL === "undefined") { answer2 = undefined }
else if (valueL === "infinity") { answer2 = Infinity }
else if (valueL === "-infinity") { answer2 = -Infinity }
else if (answer1 === "color" && valueL[0] === "#") {
var rgb = hexToRGB(valueL);
answer2 = "rgb("+rgb.r+","+rgb.g+","+rgb.b+")";
}
currentProp = answer1;
var num = parseFloat(answer2);
if (!isNaN(num)) { answer2 = num }
else if (valueL === "nan") { answer2 = NaN }
currentPropValue = answer2;
logMessage("Prop: "+currentProp);
logMessage("Value: "+currentPropValue);
},
tool: function(pixel) {
if (!currentProp) { return }
if (currentPropValue !== null && currentPropValue !== undefined && pixel[currentProp] !== undefined && typeof pixel[currentProp] !== typeof currentPropValue) {
logMessage("Error: "+currentProp+" type is "+typeof pixel[currentProp]+", not "+typeof currentPropValue+".");
currentProp = null;
currentPropValue = null;
selectElement("unknown");
return;
}
if (currentProp === "element") {
changePixel(pixel, currentPropValue);
return;
}
if (currentProp === "burning" && currentPropValue === "true") {
pixel.burnStart = pixelTicks;
return;
}
pixel[currentProp] = currentPropValue;
},
category: "special",
},
//ice color: "#c5e9f0"
"salt_ice": { color: "#b6ced4" },
"sugar_ice": { color: "#c8dee3" },
"seltzer_ice": { color: "#a7c4c9" },
"dirty_ice": { color: "#a9d9c7" },
"pool_ice": { color: "#c0eff0" },
"blood_ice": { color: "#ff7070" },
"antibody_ice": { color: "#ff8080" },
"infection_ice": { color: "#ff7090" },
};
var currentMonth = new Date().getMonth();
if (currentMonth == 9) { // October
elements.pumpkin_seed.hidden = false;
}
else if (currentMonth == 11) { // December
elements.candy.colorPattern = [
"WWRRRWWRRR",
"WWRRWWWRRW",
"WRRRWWRRRW",
"WRRWWWRRWW",
"RRRWWRRRWW",
"RRWWWRRWWW",
"RRWWRRRWWR",
"RWWWRRWWWR",
"RWWRRRWWRR",
"WWWRRWWWRR",
]
elements.candy.colorKey = {"R":"#c92626", "W":"#e3e3e3"}
elements.candy.color = ["#c92626","#e3e3e3","#c92626","#e3e3e3","#c92626"]
}
// Mod Loader
runAfterLoadList = [];
// runAfterLoad() takes a function and adds it to the runAfterLoadList.
function runAfterLoad(func) {
runAfterLoadList.push(func);
}
runAfterAutogenList = [];
function runAfterAutogen(callback) {
runAfterAutogenList.push(callback);
}
// If the localStorage key "enabledMods" exists, load it as an array.
// If it doesn't exist, create an empty array.
enabledMods = localStorage.getItem("enabledMods") ? JSON.parse(localStorage.getItem("enabledMods")) : [];
// Run all scripts in the enabledMods array, if it fails print to console
for (var i = 0; i < enabledMods.length; i++) {
try {
var script = document.createElement('script');
var src = enabledMods[i];
script.src = src;
document.head.appendChild(script);
} catch (e) {
console.log("Error in mod: " + enabledMods[i]);
console.log(e);
}
}
// if the URL contains fools=true, load the fools.js mod
if (window.location.href.includes("fools=true")) {
var script = document.createElement('script');
script.src = "mods/fools.js"
document.head.appendChild(script);
}
// Language Loader
langCode = null;
lang = {};
if (urlParams.has("lang") && urlParams.get("lang") !== "en") {
langCode = urlParams.get("lang");
}
else if (settings.lang && settings.lang !== "en") {
langCode = settings.lang;
}
if (langCode) {
try {
var Httpreq = new XMLHttpRequest();
Httpreq.open("GET","https://sandboxels.r74n.com/lang/"+langCode+".json",false);
Httpreq.send(null);
lang = JSON.parse(Httpreq.responseText);
if (lang["#lang.font"]) {
var style = document.createElement("style");
style.innerHTML = "body{font-family:'"+lang["#lang.font"]+"'!important;}"
document.head.appendChild(style);
}
}
catch { langCode = null }
}
function hexToRGB(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
function RGBToHex(rgb) {
var r = parseInt(rgb.r||rgb[0]);
var g = parseInt(rgb.g||rgb[1]);
var b = parseInt(rgb.b||rgb[2]);
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
function averageRGB(rgblist) {
var r = 0;
var g = 0;
var b = 0;
for (var i = 0; i < rgblist.length; i++) {
var rgb = rgblist[i];
r += parseInt(rgb.r||rgb[0]);
g += parseInt(rgb.g||rgb[1]);
b += parseInt(rgb.b||rgb[2]);
}
r = Math.floor(r/rgblist.length);
g = Math.floor(g/rgblist.length);
b = Math.floor(b/rgblist.length);
return "rgb("+r+","+g+","+b+")";
}
logInterval = null;
function logMessage(text) {
var logText = document.getElementById("logText");
text = text.replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/&/g, "&amp;");
logText.innerHTML += "\n"+text;
logText.innerHTML = logText.innerHTML.trim();
if (logText.innerHTML.split("\n").length > 10) {
var lines = logText.innerHTML.split("\n");
lines.shift();
logText.innerHTML = lines.join("\n");
}
if (!logInterval) {
logInterval = setInterval(function(){
var lines = logText.innerHTML.split("\n");
lines.shift();
logText.innerHTML = lines.join("\n");
if (logText.innerHTML.length === 0) {
clearInterval(logInterval);
logInterval = null;
}
}, 3000)
}
}
function clearLog() {
document.getElementById("logText").innerHTML = "";
if (logInterval) {clearInterval(logInterval);}
logInterval = null;
}
currentPixels = [];
//currentID = 0;
// Pixel class, with attributes such as x, y, and element
class Pixel {
constructor(x, y, element) {
this.x = x;
this.y = y;
if (!elements[element]) {
this.invalidElement = element;
element = "unknown";
}
this.element = element;
var elementInfo = elements[element];
if (elementInfo.colorPattern && settings.textures!==0) {
this.color = elementInfo.colorPattern[y%elementInfo.colorPattern.length][x%elementInfo.colorPattern[0].length];
}
else {
this.color = pixelColorPick(this);
}
// If element doesn't have temp attribute, set temp to airTemp
if (elementInfo.temp==undefined) {
this.temp = airTemp;
} else {
this.temp = elementInfo.temp;
}
this.start = pixelTicks;
//this.id = currentID;
//currentID++;
if (elementInfo.burning && settings.burn!==0) {
this.burning = true;
this.burnStart = pixelTicks;
}
if (elementInfo.charge) {
this.charge = elementInfo.charge;
}
// If elementInfo.flippableX, set it to true or false randomly
if (elementInfo.flipX !== undefined) { this.flipX = elementInfo.flipX }
else if (elementInfo.flippableX) {
this.flipX = Math.random() >= 0.5;
}
// If elementInfo.flippableY, set it to true or false randomly
if (elementInfo.flipY !== undefined) { this.flipY = elementInfo.flipY }
else if (elementInfo.flippableY) {
this.flipY = Math.random() >= 0.5;
}
// If elementInfo.rotatable, set it to a number between 0 and 3
if (elementInfo.r !== undefined) { this.r = elementInfo.r }
else if (elementInfo.rotatable) {
this.r = Math.floor(Math.random() * 4);
}
// If elementInfo.properties, set each key to its value
if (elementInfo.properties !== undefined) {
for (var key in elementInfo.properties) {
// If it is an array or object, make a copy of it
if (typeof elementInfo.properties[key] == "object") {
this[key] = JSON.parse(JSON.stringify(elementInfo.properties[key]));
}
else {
this[key] = elementInfo.properties[key];
}
}
}
pixelMap[x][y] = this;
if (airTemp !== 20) {pixelTempCheck(this)}
}
}
// If the screen size is under 768px, set pixelSize to 5, otherwise 6
if (window.innerWidth < 700) {
pixelSize = 5;
} else {
pixelSize = 6;
}
pixelSizeHalf = pixelSize/2;
function outOfBounds(x,y) {
// Returns true if the pixel is out of bounds
return y > height-1 || y < 1 || x > width-1 || x < 1
}
function isEmpty(x, y, ignoreBounds=false, oob=undefined) {
if (oob || outOfBounds(x,y)) {
return ignoreBounds;
}
return pixelMap[x][y] == undefined;
}
function canMove(pixel,x,y) {
if (isEmpty(x,y)) {
return true;
}
}
function movePixel(pixel,x,y,leaveBehind=null) {
// Delete the pixel from the old position
delete pixelMap[pixel.x][pixel.y];
if (leaveBehind != null && isEmpty(pixel.x,pixel.y)) { createPixel(leaveBehind,pixel.x,pixel.y); }
pixel.x = x;
pixel.y = y;
pixelMap[x][y] = pixel;
}
function clonePixel(pixel,x,y) {
currentPixels.push(new Pixel(x, y, pixel.element));
}
function createPixel(element,x,y) {
if (Array.isArray(element)) {
element = element[Math.floor(Math.random()*element.length)];
}
currentPixels.push(new Pixel(x, y, element));
checkUnlock(element);
}
function deletePixel(x,y) {
// remove pixelMap[x][y] from currentPixels
currentPixels.splice(currentPixels.indexOf(pixelMap[x][y]),1);
if (pixelMap[x][y]) {pixelMap[x][y].del = true;}
delete pixelMap[x][y];
}
function swapPixels(pixel1,pixel2) {
var tempX = pixel1.x;
var tempY = pixel1.y;
pixel1.x = pixel2.x;
pixel1.y = pixel2.y;
pixel2.x = tempX;
pixel2.y = tempY;
pixelMap[pixel1.x][pixel1.y] = pixel1;
pixelMap[pixel2.x][pixel2.y] = pixel2;
}
function changePixel(pixel,element,changetemp=true) {
if (!elements[element]) {
pixel.invalidElement = element;
element = "unknown"
}
pixel.element = element;
pixel.color = pixelColorPick(pixel);
pixel.start = pixelTicks;
var elementInfo = elements[element];
if (elementInfo.burning == true) {
pixel.burning = true;
pixel.burnStart = pixelTicks;
}
else if (pixel.burning && !elementInfo.burn) {
delete pixel.burning;
delete pixel.burnStart;
}
delete pixel.origColor; // remove stain
if (pixel.r && !elementInfo.rotatable) {
delete pixel.r;
}
if (pixel.flipX && !elementInfo.flippableX) {
delete pixel.flipX;
}
if (pixel.flipY && !elementInfo.flippableY) {
delete pixel.flipY;
}
// If elementInfo.flippableX, set it to true or false randomly
if (elementInfo.flipX !== undefined) { pixel.flipX = elementInfo.flipX }
else if (elementInfo.flippableX) {
pixel.flipX = Math.random() >= 0.5;
}
// If elementInfo.flippableY, set it to true or false randomly
if (elementInfo.flipY !== undefined) { pixel.flipY = elementInfo.flipY }
else if (elementInfo.flippableY) {
pixel.flipY = Math.random() >= 0.5;
}
if (elementInfo.temp !== undefined && changetemp) {
pixel.temp = elementInfo.temp;
pixelTempCheck(pixel)
}
if (pixel.con && !elementInfo.canContain) {
delete pixel.con;
}
// If elementInfo.properties, set each key to its value
if (elementInfo.properties !== undefined) {
for (var key in elementInfo.properties) {
// If it is an array or object, make a copy of it
if (typeof elementInfo.properties[key] == "object") {
pixel[key] = JSON.parse(JSON.stringify(elementInfo.properties[key]));
}
else {
pixel[key] = elementInfo.properties[key];
}
}
}
checkUnlock(element);
}
function reactPixels(pixel1,pixel2) {
var r = elements[pixel1.element].reactions[pixel2.element];
if (r.setting && settings[r.setting]===0) {
return false;
}
// r has the attribute "y" which is a range between two y values
// r.y example: [10,30]
// return false if y is defined and pixel1's y is not in the range
if (r.tempMin !== undefined && pixel1.temp < r.tempMin) {
return false;
}
if (r.tempMax !== undefined && pixel1.temp > r.tempMax) {
return false;
}
if (r.burning1 !== undefined && Boolean(pixel1.burning) !== r.burning1) {
return false;
}
if (r.burning2 !== undefined && Boolean(pixel2.burning) !== r.burning2) {
return false;
}
if (r.charged && !pixel.charge) {
return false;
}
if (r.chance !== undefined && Math.random() > r.chance) {
return false;
}
if (r.y !== undefined && (pixel1.y < r.y[0] || pixel1.y > r.y[1])) {
return false;
}
if (r.elem1 !== undefined) {
// if r.elem1 is an array, set elem1 to a random element from the array, otherwise set it to r.elem1
if (Array.isArray(r.elem1)) {
var elem1 = r.elem1[Math.floor(Math.random() * r.elem1.length)];
} else { var elem1 = r.elem1; }
if (elem1 == null) {
deletePixel(pixel1.x,pixel1.y);
}
else {
changePixel(pixel1,elem1);
}
}
if (r.charge1) { pixel1.charge = r.charge1; }
if (r.temp1) { pixel1.temp += r.temp1; pixelTempCheck(pixel1); }
if (r.color1) { // if it's a list, use a random color from the list, else use the color1 attribute
pixel1.color = pixelColorPick(pixel1, Array.isArray(r.color1) ? r.color1[Math.floor(Math.random() * r.color1.length)] : r.color1);
}
if (r.attr1) { // add each attribute to pixel1
for (var key in r.attr1) {
pixel1[key] = r.attr1[key];
}
}
if (r.stain1) { stainPixel(pixel1,r.stain1,0.05); }
if (r.elem2 !== undefined) {
// if r.elem2 is an array, set elem2 to a random element from the array, otherwise set it to r.elem2
if (Array.isArray(r.elem2)) {
var elem2 = r.elem2[Math.floor(Math.random() * r.elem2.length)];
} else { var elem2 = r.elem2; }
if (elem2 == null) {
deletePixel(pixel2.x,pixel2.y);
}
else {
changePixel(pixel2,elem2);
}
}
if (r.charge2) { pixel2.charge = r.charge2; }
if (r.temp2) { pixel2.temp += r.temp2; pixelTempCheck(pixel2); }
if (r.color2) { // if it's a list, use a random color from the list, else use the color2 attribute
pixel2.color = pixelColorPick(pixel2, Array.isArray(r.color2) ? r.color2[Math.floor(Math.random() * r.color2.length)] : r.color2);
}
if (r.attr2) { // add each attribute to pixel2
for (var key in r.attr2) {
pixel2[key] = r.attr2[key];
}
}
if (r.stain2) { stainPixel(pixel2,r.stain2,0.05); }
if (r.func) { r.func(pixel1,pixel2); }
return r.elem1!==undefined || r.elem2!==undefined;
}
loadedSounds = {};
function playSound(sound) {
if (loadedSounds[sound] === undefined) {
loadedSounds[sound] = new Audio("sounds/" + sound);
}
loadedSounds[sound].play();
}
function stopSound(sound) {
if (loadedSounds[sound] === undefined) {
loadedSounds[sound] = new Audio("sounds/" + sound);
}
loadedSounds[sound].pause();
loadedSounds[sound].currentTime = 0;
}
function loopSound(sound) {
if (loadedSounds[sound] === undefined) {
loadedSounds[sound] = new Audio("sounds/" + sound);
}
loadedSounds[sound].loop = true;
loadedSounds[sound].play();
}
validDensitySwaps = {
"solid": {
"liquid": true,
"gas": true
},
"liquid": {
"liquid": true,
"gas": true
},
"gas": {
"gas": true
},
undefined: {}
}
function tryMove(pixel,nx,ny,leaveBehind,force) {
if (pixel.drag && !force) { return true; }
var info = elements[pixel.element];
var oob = outOfBounds(nx,ny);
if (isEmpty(nx,ny,false,oob)) { // If coords is empty, move to coords
movePixel(pixel,nx,ny,leaveBehind);
return true;
}
else if (!oob) {
// Reactions
newPixel = pixelMap[nx][ny];
var rr1 = false;
if (info.reactions !== undefined && info.reactions[newPixel.element] !== undefined) {
rr1 = reactPixels(pixel,newPixel)
if (rr1) {
return true;
}
}
if (!rr1 && elements[newPixel.element].reactions !== undefined && elements[newPixel.element].reactions[pixel.element] !== undefined && !elements[newPixel.element].reactions[pixel.element].oneway) {
if (reactPixels(newPixel,pixel)) {
return true;
}
}
// Density
if (elements[pixel.element].id !== elements[newPixel.element].id) {
if (info.density !== undefined && elements[newPixel.element].density !== undefined) {
// if the pixel's state + ">" + newPixel's state is in validDensitySwaps, and the pixel's density is larger than the newPixel's density, swap the pixels
if (validDensitySwaps[info.state][elements[newPixel.element].state] && info.density >= elements[newPixel.element].density) {
// chance depending on the difference in density
if (Math.random() < (info.density - elements[newPixel.element].density)/(info.density + elements[newPixel.element].density)) {
swapPixels(pixel,newPixel);
return true;
}
}
}
}
// else { // same-element density swapping
// if (info.density !== undefined) {
// if (validDensitySwaps[info.state][info.state]) {
// if (Math.random() < 0.01) {
// swapPixels(pixel,newPixel);
// return true;
// }
// }
// }
// }
}
return false;
}
function behaviorCoords(x,y,bx,by) {
return {x:x+bx-1,y:y+by-1};
}
function relativeCoords(x,y,bx,by) {
return {x:bx-1,y:by-1};
}
/* Behavior Example (Sand)
[
["XX","XX","XX"],
["XX","XX","XX"],
["M2","M1","M2"]
] */
behaviorCache = {};
function rotateBehavior(behavior,rotation) {
// returns rotated 2D array counter-clockwise depending on rotation 1, 2, or 3
// if the rotation is under 0, subtract it from 3
if (rotation < 0) {
rotation = 4 + rotation;
}
var check = behaviorCache[behavior.toString()+rotation];
if (check != undefined) { return check; }
var newBehavior = []
if (rotation == 1) {
// rotate counter-clockwise 90 degrees
for (var i = 0; i < behavior.length; i++) {
newBehavior[i] = [];
for (var j = 0; j < behavior[i].length; j++) {
newBehavior[i][j] = behavior[j][behavior.length-1-i];
}}
}
else if (rotation == 2) {
// rotate counter-clockwise 180 degrees
for (var i = 0; i < behavior.length; i++) {
newBehavior[i] = [];
for (var j = 0; j < behavior[i].length; j++) {
newBehavior[i][j] = behavior[behavior.length-1-i][behavior[i].length-1-j];
}}
}
else if (rotation == 3) {
// rotate counter-clockwise 270 degrees
for (var i = 0; i < behavior.length; i++) {
newBehavior[i] = [];
for (var j = 0; j < behavior[i].length; j++) {
newBehavior[i][j] = behavior[behavior[i].length-1-j][i];}
}
}
else {
// no rotation
return behavior;
}
behaviorCache[behavior.toString()+rotation] = newBehavior;
return newBehavior;
}
function flipBehavior(behavior,axis) {
// returns flipped 2D array depending on axis "x" or "y"
var check = behaviorCache[behavior.toString()+axis];
if (check != undefined) { return check; }
if (axis === "x") {
var newBehavior = [];
for (var i = 0; i < behavior.length; i++) {
newBehavior[i] = [];
for (var j = 0; j < behavior[i].length; j++) {
newBehavior[i][j] = behavior[i][behavior[i].length-1-j];
}}
behaviorCache[behavior.toString()+axis] = newBehavior;
return newBehavior;
}
else { // axis === y
newBehavior = behavior.slice().reverse();
behaviorCache[behavior.toString()+axis] = newBehavior;
return newBehavior;
}
return behavior;
}
/* Behavior Rules
XX = Ignore
M1 = Move (First Priority)
M2 = Move (Second Priority)
SP = Support (Doesn't move if all aren't empty)
SA = Support Any (Doesn't move if any aren't empty)
DL = Delete
DB = Delete Both (Self and target)
CL = Clone
CF = Clone first touched
CH = Change
C2 = Change Self after M2
CR:element_name = Create a pixel of element_name
LB:element_name = Leave behind a pixel of element_name when moved (Must be center cell)
L1:element_name = Leave behind only on M1 moves
L2:element_name = Leave behind only on M2 moves
SW = Swap
HT = Heat
CO = Cool
CC = Change Color (Hexadecimal)
ST = Stick
SH = Shock with electricity
FX = Flip X
FY = Flip Y
RT = Rotate
BO = Bounce off of
EX:radius>fire substitute = Explode on touch
%number = Chance of rule happening
*/
function pixelTick(pixel,custom=null) {
if (pixel.start === pixelTicks) {return}
if (elements[pixel.element] === undefined) {
pixel.invalidElement = pixel.element;
changePixel(pixel,"unknown");
return;
}
var info = elements[pixel.element];
if (custom) { var behavior = custom; }
else if (pixel.charge && info.behaviorOn) { var behavior = info.behaviorOn; }
else { var behavior = info.behavior; }
if (pixel.flipX) { behavior = flipBehavior(behavior,"x"); }
if (pixel.flipY) { behavior = flipBehavior(behavior,"y"); }
if (pixel.r) { behavior = rotateBehavior(behavior,pixel.r); }
var x = pixel.x;
var y = pixel.y;
var move1Spots = [];
var move2Spots = [];
var supportSpots = [];
var swapSpots = [];
var leaveBehind = null;
var leaveBehind1 = null;
var leaveBehind2 = null;
var move = true;
// Parse behavior
for (var by = 0; by < behavior.length; by++) {
var behaviorby = behavior[by];
for (var bx = 0; bx < behaviorby.length; bx++) {
var b0 = behaviorby[bx];
if (b0 === "XX") {continue}
//if (b.includes(" OR ")) {
// b = b.split(" OR ")[Math.floor(Math.random()*b.split(" OR ").length)];
//}
// Loop through b0.split(" AND ")
if (b0.indexOf(" AND ") !== -1) { var andsplit = b0.split(" AND "); }
else { var andsplit = [b0]; }
for (var i = 0; i < andsplit.length; i++) {
var b = andsplit[i];
if (b.indexOf(":") !== -1) {
var arg = b.split(":")[1].split(/[\:\%]/)[0];
if (b.indexOf("%") === -1) {
b = b.split(/[\:\%]/)[0];
}
}
else { var arg = null;}
// If b has "%" followed by a number in it, it's a chance to move
if (b.indexOf("%") !== -1) {
// Split the string at the "%" and use the second half as the chance (float)
var chance = parseFloat(b.split("%")[1]);
//console.log(b+": "+(Math.random()*100 < chance));
b = b.split(/[\:\%]/)[0];
}
else { var chance = 100; }
if (chance===100 || Math.random()*100 < chance) {
var newCoords = behaviorCoords(x,y,bx,by);
switch (b) {
default: break;
case "M1":
if (info.viscosity !== undefined) {
if (!((Math.random()*100) < 100 / Math.pow(info.viscosity, 0.25))) {
newCoords.x = x;
}
}
move1Spots.push(newCoords);
break;
case "M2":
if (info.viscosity !== undefined) {
if (!((Math.random()*100) < 100 / Math.pow(info.viscosity, 0.25))) {
newCoords.x = x;
}
}
move2Spots.push(newCoords);
break;
case "SP":
supportSpots.push({x:newCoords.x,y:newCoords.y,arg:arg});
break;
case "SA":
if (!isEmpty(newCoords.x,newCoords.y,true)) {
move = false;
}
break;
case "DL":
if (!isEmpty(newCoords.x,newCoords.y,true)) {
// if the pixel at newCoords is the same element as the pixel, ignore
newPixel = pixelMap[newCoords.x][newCoords.y];
// if info.ignore exists and newPixel.element is in it
if (info.ignore && info.ignore.indexOf(newPixel.element) !== -1) {
continue;
}
if ((!(newPixel.element == pixel.element)) || (newCoords.x == x && newCoords.y == y)) {
if (arg != null) { var args = arg.split(","); }
if (arg == null || args.indexOf(newPixel.element) !== -1) {
if (!elements[newPixel.element].hardness || Math.random() > elements[newPixel.element].hardness) {
deletePixel(newCoords.x,newCoords.y);
if (newCoords.x == x && newCoords.y == y) {
var deleted = true;
}
swapSpots = [];
}
}
}
}
break;
case "DB":
if (!isEmpty(newCoords.x,newCoords.y,true)) {
// if the pixel at newCoords is the same element as the pixel, ignore
newPixel = pixelMap[newCoords.x][newCoords.y];
// if info.ignore exists and newPixel.element is in it
if (info.ignore && info.ignore.indexOf(newPixel.element) !== -1) {
continue;
}
if (!(newPixel.element == pixel.element)) {
if (arg != null) { var args = arg.split(","); }
if (arg == null || args.indexOf(newPixel.element) !== -1) {
if (!elements[newPixel.element].hardness || Math.random() > elements[newPixel.element].hardness) {
deletePixel(newCoords.x,newCoords.y);
if (pixelMap[pixel.x][pixel.y] != undefined) {
deletePixel(pixel.x,pixel.y);
}
var deleted = true;
swapSpots = [];
}
}
}
}
break;
case "CH":
if (!isEmpty(newCoords.x,newCoords.y,true)) {
var newPixel = pixelMap[newCoords.x][newCoords.y];
if (info.ignore && info.ignore.indexOf(newPixel.element) !== -1) {
continue;
}
if (!elements[newPixel.element].hardness || Math.random() > elements[newPixel.element].hardness || (newCoords.x == x && newCoords.y == y)) {
if (arg.indexOf(">") !== -1) {
var argfrom = arg.split(">")[0];
if (argfrom.indexOf(",") !== -1) {
if (argfrom.split(",").indexOf(newPixel.element) === -1) {
continue;
}
}
else if (argfrom !== newPixel.element) {
continue;
}
var argto = arg.split(">")[1];
}
else {
var argfrom = null;
var argto = arg;
}
if (argto.indexOf(",") !== -1) {
var argto = argto.split(",")[Math.floor(Math.random()*argto.split(",").length)];
}
if (elements[argto]) {
if (elements[newPixel.element].id !== elements[argto].id) {
changePixel(newPixel,argto);
}
}
}
}
break;
case "SW":
if (!isEmpty(newCoords.x,newCoords.y,true)) {
var newPixel = pixelMap[newCoords.x][newCoords.y];
if (arg != null) { var args = arg.split(","); }
if (arg == null || args.indexOf(newPixel.element) !== -1) {
if (!elements[newPixel.element].hardness || Math.random() > elements[newPixel.element].hardness) {
swapSpots.push({x:newCoords.x,y:newCoords.y});
}
}
}
break;
case "CR":
if (isEmpty(newCoords.x,newCoords.y)) {
if (arg == null) {
arg = pixel.element;
}
else if (arg.indexOf(",") !== -1) {
arg = arg.split(",")[Math.floor(Math.random()*arg.split(",").length)];
}
if (elements[arg]) {
createPixel(arg,newCoords.x,newCoords.y);
if (info.fireColor && arg==="fire") {
pixelMap[newCoords.x][newCoords.y].color = pixelColorPick(pixelMap[newCoords.x][newCoords.y],info.fireColor);
}
pixelMap[newCoords.x][newCoords.y].temp = pixel.temp
pixelTempCheck(pixelMap[newCoords.x][newCoords.y]);
}
}
break;
case "CL":
if (isEmpty(newCoords.x,newCoords.y)) {
if (arg == null || pixel.temp >= parseFloat(arg)) {
clonePixel(pixel,newCoords.x,newCoords.y);
}
}
break;
case "CF":
if (pixel.clone) {
if (isEmpty(newCoords.x,newCoords.y)) {
createPixel(pixel.clone,newCoords.x,newCoords.y);
pixelMap[newCoords.x][newCoords.y].temp = pixel.temp;
pixelTempCheck(pixelMap[newCoords.x][newCoords.y]);
}
}
else {
if (!isEmpty(newCoords.x,newCoords.y,true)) {
newPixel = pixelMap[newCoords.x][newCoords.y];
if (info.ignore && info.ignore.indexOf(newPixel.element) !== -1) {
continue;
}
if (newPixel.element != pixel.element && newPixel.element != "wire") {
pixel.clone = newPixel.element;
pixel.temp = newPixel.temp;
}
else if (newPixel.clone) {
pixel.clone = newPixel.clone;
pixel.temp = newPixel.temp;
}
}
}
break;
case "SH":
if (!isEmpty(newCoords.x,newCoords.y,true)) {
var newPixel = pixelMap[newCoords.x][newCoords.y];
var con = elements[newPixel.element].conduct;
if (con != undefined) {
if (Math.random() < con) { // If random number is less than conductivity
if (!newPixel.charge && !newPixel.chargeCD && (arg == null || newPixel.element == arg)) {
newPixel.charge = (parseFloat(arg) || 1);
if (elements[newPixel.element].colorOn) {
newPixel.color = pixelColorPick(newPixel);
}
}
}
}
}
break;
case "ST": //Stick
if (!isEmpty(newCoords.x,newCoords.y,true)) {
var newPixel = pixelMap[newCoords.x][newCoords.y];
if (info.ignore && info.ignore.indexOf(newPixel.element) !== -1) {
continue;
}
if (newPixel.element != pixel.element && (arg == null || newPixel.element == arg)) {
var sticking = true
}
}
break;
case "LB":
case "L1":
case "L2":
if (arg != null && arg.indexOf(",") !== -1) {
arg = arg.split(",")[Math.floor(Math.random()*arg.split(",").length)];
}
if (elements[arg]) {
if (b=="LB") {leaveBehind = arg;}
else if (b=="L1") {leaveBehind1 = arg;}
else if (b=="L2") {leaveBehind2 = arg;}
}
break;
case "CC":
if (!isEmpty(newCoords.x,newCoords.y,true)) {
var newPixel = pixelMap[newCoords.x][newCoords.y];
if (arg == null) {arg = newPixel.colorObject}
else {
if (arg.indexOf(",") !== -1) {
arg = arg.split(",")[Math.floor(Math.random()*arg.split(",").length)];
}
if (!arg.startsWith("#")) {
arg = "#" + arg;
}
}
newPixel.color = pixelColorPick(newPixel,arg);
}
break;
case "HT":
if (!isEmpty(newCoords.x,newCoords.y,true)) {
var newPixel = pixelMap[newCoords.x][newCoords.y];
// if the element isn't the same or the coords ARE the same
if (!(newPixel.element == pixel.element) || (newCoords.x == pixel.x && newCoords.y == pixel.y)) {
if (arg != null) {arg = parseFloat(arg)}
else {arg = 1}
if (isNaN(arg)) {arg = 1}
newPixel.temp += arg;
pixelTempCheck(newPixel);
}
}
break;
case "CO":
if (!isEmpty(newCoords.x,newCoords.y,true)) {
var newPixel = pixelMap[newCoords.x][newCoords.y];
if (!(newPixel.element == pixel.element) || (newCoords.x == pixel.x && newCoords.y == pixel.y)) {
if (arg != null) {arg = parseFloat(arg)}
else {arg = 1}
if (isNaN(arg)) {arg = 1}
newPixel.temp -= arg;
pixelTempCheck(newPixel);
}
}
break;
case "FX":
if (!isEmpty(newCoords.x,newCoords.y,true)) {
var newPixel = pixelMap[newCoords.x][newCoords.y];
if (elements[newPixel.element].flippableX) {
if (arg === "0") { newPixel.flipX = false; }
else if (arg === "1") { newPixel.flipX = true; }
newPixel.flipX = !newPixel.flipX;
}
}
break;
case "FY":
if (!isEmpty(newCoords.x,newCoords.y,true)) {
var newPixel = pixelMap[newCoords.x][newCoords.y];
if (elements[newPixel.element].flippableY) {
if (arg === "0") { newPixel.flipY = false; }
else if (arg === "1") { newPixel.flipY = true; }
else { newPixel.flipY = !newPixel.flipY; }
}
}
break;
case "RT":
if (!isEmpty(newCoords.x,newCoords.y,true)) {
var newPixel = pixelMap[newCoords.x][newCoords.y];
// If arg isn't null, set arg to a random choice from arg.split(",")
if (arg != null && arg.indexOf(",") !== -1) {
arg = arg.split(",")[Math.floor(Math.random()*arg.split(",").length)];
}
if (elements[newPixel.element].rotatable) {
newPixel.r = ((newPixel.r||0) + (parseInt(arg)||1)) % 4;
}
}
break;
case "BO":
if (!isEmpty(newCoords.x,newCoords.y) && (outOfBounds(newCoords.x,newCoords.y) || elements[pixelMap[newCoords.x][newCoords.y].element].id === elements[pixel.element].id || elements[pixelMap[newCoords.x][newCoords.y].element].state === "solid")) {
if (info.flippableX) {
pixel.flipX = !pixel.flipX;
}
if (info.flippableY) {
pixel.flipY = !pixel.flipY;
}
if (info.rotatable) {
// If arg isn't null, set arg to a random choice from arg.split(",")
if (arg != null && arg.indexOf(",") !== -1) {
arg = arg.split(",")[Math.floor(Math.random()*arg.split(",").length)];
}
if (pixel.r !== undefined) {
pixel.r = (pixel.r + (parseInt(arg)||2)) % 4;
}
else { pixel.r = (parseInt(arg)||2); }
}
}
break;
case "C2":
if (arg.indexOf(",") !== -1) {
arg = arg.split(",")[Math.floor(Math.random()*arg.split(",").length)];
}
var C2 = arg;
break;
case "EX":
if (!isEmpty(newCoords.x,newCoords.y)) {
if (outOfBounds(newCoords.x,newCoords.y) || (newCoords.x == x && newCoords.y == y) || (pixel.element !== pixelMap[newCoords.x][newCoords.y].element && elements[pixelMap[newCoords.x][newCoords.y].element].state !== "gas")) {
// if arg contains ">", var fire = everything after it, arg = everything before it
if (arg.indexOf(">") !== -1) {
var fire = arg.split(">")[1];
arg = arg.split(">")[0];
}
else { var fire = "fire" }
// arg = a number
if (arg != null) {
arg = parseInt(arg);
if (isNaN(arg)) {arg = 3}
}
else {arg = 3}
explodeAt(x,y,arg,fire);
if (!pixel.del && info.hardness !== 1) {
deletePixel(x,y);
var deleted = true;
}
swapSpots = [];
}
}
break;
}
}
}
}
}
if (typeof deleted !== "undefined") {return;}
if (supportSpots.length > 0) {
var supportCount = 0;
var allEmpty = true;
for (var i = 0; i < supportSpots.length; i++) {
var bx = supportSpots[i].x;
var by = supportSpots[i].y;
var arg = supportSpots[i].arg;
if (!isEmpty(bx,by,true)) {
if (info.ignore && info.ignore.indexOf(pixelMap[bx][by].element) !== -1) {continue;}
if ((arg == null && !validDensitySwaps[info.state][elements[pixelMap[bx][by].element].state]) || pixelMap[bx][by].element == arg) {
supportCount++;
}
}
}
if (supportCount == supportSpots.length) {
move = false;
}
}
var moved = false;
if (swapSpots.length > 0) {
var coords = swapSpots[Math.floor(Math.random()*swapSpots.length)];
if (pixelMap[coords.x][coords.y] != undefined) {
swapPixels(pixel,pixelMap[coords.x][coords.y]);
move = false;
moved = true;
}
}
if (typeof sticking !== "undefined") {
move = false;
}
// Move First Priority
if (move) {
if (move1Spots.length > 0) {
// While move1Spots is not empty
while (move1Spots.length > 0) {
// coords = random item of move1Spots
var coords = move1Spots[Math.floor(Math.random()*move1Spots.length)];
var nx = coords.x;
var ny = coords.y;
moved = tryMove(pixel,nx,ny,leaveBehind1 || leaveBehind);
if (moved) {
break;
}
else {
// remove coords from move1Spots
move1Spots.splice(move1Spots.indexOf(coords),1);
}
}
}
// Move Second Priority
if (!moved && move2Spots.length > 0) {
// While move2Spots is not empty
while (move2Spots.length > 0) {
// coords = random item of move2Spots
var coords = move2Spots[Math.floor(Math.random()*move2Spots.length)];
var nx = coords.x;
var ny = coords.y;
moved = tryMove(pixel,nx,ny,leaveBehind2 || leaveBehind);
if (moved) {
if (typeof C2 !== "undefined" && elements[C2]) {
changePixel(pixel,C2);
}
break;
}
else {
// remove coords from move2Spots
move2Spots.splice(move2Spots.indexOf(coords),1);
}
}
}
}
doAirDensity(pixel);
// Change tempearture if needed (unused)
/*if (info.tempChange != undefined) {
pixel.temp += info.tempChange;
pixelTempCheck(pixel);
}*/
// Burning
doBurning(pixel);
// Heat Transfer
if (info.insulate !== true) {
doHeat(pixel);
}
// Electricity Transfer
doElectricity(pixel);
// Staining
if (info.stain) {
doStaining(pixel);
}
}
function doDefaults(pixel) {
if (pixel.del) {return}
var info = elements[pixel.element];
if (info.insulate !== true) {doHeat(pixel)};
doAirDensity(pixel);
doBurning(pixel);
doElectricity(pixel);
if (info.stain) { doStaining(pixel) };
}
function doAirDensity(pixel) {
if (pixel.del) {return}
var info = elements[pixel.element];
if (!info.ignoreAir && info.density !== undefined && info.movable === true && info.density < airDensity) {
// Air Density
// if the pixel's state + ">" + newPixel's state is in validDensitySwaps, and the pixel's density is larger than the newPixel's density, swap the pixels
if (validDensitySwaps.gas[info.state]) {
// chance depending on the difference in density
if (Math.random() < (airDensity - info.density)/(airDensity + info.density)) {
tryMove(pixel,pixel.x,pixel.y-1);
}
}
}
}
function doBurning(pixel) {
if (settings.burn === 0) { return }
if (pixel.burning) { // Burning
var info = elements[pixel.element];
pixel.temp += 1;
pixelTempCheck(pixel);
if (pixel.temp < 0) {
delete pixel.burning;
delete pixel.burnStart;
return;
}
for (var i = 0; i < adjacentCoords.length; i++) { // Burn adjacent pixels
var x = pixel.x+adjacentCoords[i][0];
var y = pixel.y+adjacentCoords[i][1];
if (!isEmpty(x,y,true)) {
var newPixel = pixelMap[x][y];
if (elements[newPixel.element].burn && !newPixel.burning) {
if (Math.floor(Math.random()*100) < elements[newPixel.element].burn) {
newPixel.burning = true;
newPixel.burnStart = pixelTicks;
}
}
if (elements[newPixel.element].extinguish && elements[pixel.element].burning !== true) {
delete pixel.burning;
delete pixel.burnStart;
return;
}
}
}
if ((pixelTicks - pixel.burnStart > (info.burnTime || 200)) && Math.floor(Math.random()*100)<(info.burn || 10)) {
var burnInto = info.burnInto;
if (burnInto == undefined) {
burnInto = 'fire';
}
else if (burnInto instanceof Array) {
burnInto = burnInto[Math.floor(Math.random()*burnInto.length)];
}
changePixel(pixel,burnInto);
if (info.fireColor != undefined && burnInto == "fire") {
pixel.color = pixelColorPick(pixel,info.fireColor);
}
else {
pixel.color = pixelColorPick(pixel)
}
}
else if (Math.floor(Math.random()*100)<10 && info.id !== elements.fire.id && info.fireElement !== null) { // Spawn fire
if (isEmpty(pixel.x,pixel.y-1)) {
createPixel((info.fireElement || "fire"),pixel.x,pixel.y-1);
pixelMap[pixel.x][pixel.y-1].temp = pixel.temp//+(pixelTicks - (pixel.burnStart || 0));
if (info.fireColor != undefined) {
pixelMap[pixel.x][pixel.y-1].color = pixelColorPick(pixelMap[pixel.x][pixel.y-1],info.fireColor);
}
}
// same for below if top is blocked
else if (isEmpty(pixel.x,pixel.y+1)) {
createPixel((info.fireElement || "fire"),pixel.x,pixel.y+1);
pixelMap[pixel.x][pixel.y+1].temp = pixel.temp//+(pixelTicks - (pixel.burnStart || 0));
if (info.fireColor != undefined) {
pixelMap[pixel.x][pixel.y+1].color = pixelColorPick(pixelMap[pixel.x][pixel.y+1],info.fireColor);
}
}
}
}
}
function doHeat(pixel) {
// Check right and bottom adjacent pixels
for (var i = 0; i < biCoords.length; i++) {
var x = pixel.x+biCoords[i][0];
var y = pixel.y+biCoords[i][1];
if (!isEmpty(x,y,true)) {
var newPixel = pixelMap[x][y];
// Skip if both temperatures are the same
if (pixel.temp == newPixel.temp || elements[newPixel.element].insulate == true) {
continue;
}
// Set both pixel temperatures to their average
var avg = (pixel.temp + newPixel.temp)/2;
pixel.temp = avg;
newPixel.temp = avg;
pixelTempCheck(pixel);
pixelTempCheck(newPixel);
}
}
}
function doElectricity(pixel) {
if (pixel.charge) {
// Check each adjacent pixel, if that pixel's charge is false, set it to the same charge
for (var i = 0; i < adjacentCoords.length; i++) {
var x = pixel.x+adjacentCoords[i][0];
var y = pixel.y+adjacentCoords[i][1];
if (!isEmpty(x,y,true)) {
var newPixel = pixelMap[x][y];
var con = elements[newPixel.element].conduct;
if (con == undefined) {continue}
if (Math.random() < con) { // If random number is less than conductivity
if (!newPixel.charge && !newPixel.chargeCD) {
newPixel.charge = 1;
if (elements[newPixel.element].colorOn) {
newPixel.color = pixelColorPick(newPixel);
}
}
}
else if (elements[newPixel.element].insulate != true) { // Otherwise heat the pixel (Resistance simulation)
newPixel.temp += pixel.charge/4;
pixelTempCheck(newPixel);
}
}
}
pixel.charge -= 0.25;
if (pixel.charge <= 0) {
delete pixel.charge;
pixel.chargeCD = 4;
}
}
// Lower charge cooldown
else if (pixel.chargeCD) {
pixel.chargeCD -= 1;
if (pixel.chargeCD <= 0) {
delete pixel.chargeCD;
if (elements[pixel.element].colorOn) {
pixel.color = pixelColorPick(pixel);
}
}
}
}
solidStates = {solid:true};
liquidStates = {liquid:true};
gasStates = {gas:true};
function doStaining(pixel) {
if (settings.stain===0) { return }
var stain = elements[pixel.element].stain;
if (stain > 0) {
var newColor = pixel.color.match(/\d+/g);
}
else {
var newColor = null;
}
for (var i = 0; i < adjacentCoords.length; i++) {
var x = pixel.x+adjacentCoords[i][0];
var y = pixel.y+adjacentCoords[i][1];
if (!isEmpty(x,y,true)) {
var newPixel = pixelMap[x][y];
if (elements[pixel.element].ignore && elements[pixel.element].ignore.indexOf(newPixel.element) !== -1) {
continue;
}
if ((elements[newPixel.element].id !== elements[pixel.element].id || elements[newPixel.element].stainSelf) && (solidStates[elements[newPixel.element].state] || elements[newPixel.element].id === elements[pixel.element].id)) {
if (Math.random() < Math.abs(stain)) {
if (stain < 0) {
if (newPixel.origColor) {
newColor = newPixel.origColor;
}
else { continue; }
}
else if (!newPixel.origColor) {
newPixel.origColor = newPixel.color.match(/\d+/g);
}
// if newPixel.color doesn't start with rgb, continue
if (!newPixel.color.match(/^rgb/)) { continue; }
// parse rgb color string of newPixel rgb(r,g,b)
var rgb = newPixel.color.match(/\d+/g);
if (elements[pixel.element].stainSelf && elements[newPixel.element].id === elements[pixel.element].id) {
// if rgb and newColor are the same, continue
if (rgb[0] === newColor[0] && rgb[1] === newColor[1] && rgb[2] === newColor[2]) { continue; }
var avg = [];
for (var j = 0; j < rgb.length; j++) {
avg[j] = Math.round((rgb[j]*(1-Math.abs(stain))) + (newColor[j]*Math.abs(stain)));
}
}
else {
// get the average of rgb and newColor, more intense as stain reaches 1
var avg = [];
for (var j = 0; j < rgb.length; j++) {
avg[j] = Math.floor((rgb[j]*(1-Math.abs(stain))) + (newColor[j]*Math.abs(stain)));
}
}
// set newPixel color to avg
newPixel.color = "rgb("+avg.join(",")+")";
}
}
}
}
}
function stainPixel(newPixel,color,intensity) {
if (!newPixel.color.match(/^rgb/)) { return; }
if (!intensity) { intensity = 0.5 }
if (color.charCodeAt(0) === 35) { //
color = hexToRGB(color);
color = [color.r,color.g,color.b];
}
var rgb = newPixel.color.match(/\d+/g);
var avg = [];
for (var j = 0; j < rgb.length; j++) {
avg[j] = Math.floor((rgb[j]*(1-Math.abs(intensity))) + (color[j]*Math.abs(intensity)));
}
newPixel.color = "rgb("+avg.join(",")+")";
}
function pixelColorPick(pixel,customColor=null) {
var element = pixel.element;
var elementInfo = elements[element];
//if (elementInfo.behavior instanceof Array) {
if (pixel.charge && elementInfo.colorOn) {
customColor = elementInfo.colorOn;
}
if (customColor != null) {
if (Array.isArray(customColor)) {
customColor = customColor[Math.floor(Math.random() * customColor.length)];
}
if (customColor.startsWith("#")) {
customColor = hexToRGB(customColor);
}
var rgb = customColor;
}
else {
var rgb = elements[element].colorObject; // {r, g, b}
// If rgb is an array, choose a random item
if (Array.isArray(rgb)) {
rgb = rgb[Math.floor(Math.random() * rgb.length)];
}
}
// Randomly darken or lighten the RGB color
var coloroffset = Math.floor(Math.random() * (Math.random() > 0.5 ? -1 : 1) * Math.random() * 15);
var r = rgb.r + coloroffset;
var g = rgb.g + coloroffset;
var b = rgb.b + coloroffset;
// Make sure the color is within the RGB range
r = Math.max(0, Math.min(255, r));
g = Math.max(0, Math.min(255, g));
b = Math.max(0, Math.min(255, b));
var color = "rgb("+r+","+g+","+b+")";
/*}
else {
var color = elementInfo.color;
if (Array.isArray(color)) {
color = color[Math.floor(Math.random() * color.length)];
}
}*/
return color;
}
function pixelTempCheck(pixel) {
if (pixel.del) { return }
var elementInfo = elements[pixel.element];
if (pixel.temp < absoluteZero) { // Absolute Zero
pixel.temp = absoluteZero;
}
// If the pixel's temp >= the elementInfo tempHigh, change pixel.element to elementInfo.stateHigh
if (pixel.temp >= elementInfo.tempHigh) {
var result = elementInfo.stateHigh;
if (elementInfo.extraTempHigh) {
for (var extraTemp in elementInfo.extraTempHigh) {
if (pixel.temp >= extraTemp) {
result = elementInfo.extraTempHigh[extraTemp];
}
}
}
// If result is an array, choose a random item
if (Array.isArray(result)) {
result = result[Math.floor(Math.random() * result.length)];
}
if (result === null) {deletePixel(pixel.x,pixel.y);return false}
else {
if (elements[result].customColor) {
changePixel(pixel,result,false);
pixel.color = color;
}
else if (elementInfo.stateHighColor) {
changePixel(pixel,result,false);
pixel.color = pixelColorPick(pixel,elementInfo.stateHighColor);
}
else if (elementInfo.stateHighColorMultiplier) {
var color = pixel.color;
changePixel(pixel,result,false);
var rgb = color.match(/\d+/g);
var m = elementInfo.stateHighColorMultiplier;
if (Array.isArray(m)) {
m = m[Math.floor(Math.random() * m.length)];
}
var r = Math.floor(rgb[0] * m);
var g = Math.floor(rgb[1] * m);
var b = Math.floor(rgb[2] * m);
// Make sure the color is within the RGB range
r = Math.max(0, Math.min(255, r));
g = Math.max(0, Math.min(255, g));
b = Math.max(0, Math.min(255, b));
pixel.color = "rgb("+r+","+g+","+b+")";
}
else { changePixel(pixel,result,false); }
if (elementInfo.fireColor && result==="fire") {
pixel.color = pixelColorPick(pixel,elementInfo.fireColor);
}
}
}
// If the pixel's temp <= the elementInfo tempLow, change pixel.element to elementInfo.stateLow
else if (pixel.temp <= elementInfo.tempLow) {
var result = elementInfo.stateLow;
if (elementInfo.extraTempLow) {
for (var extraTemp in elementInfo.extraTempLow) {
if (pixel.temp <= extraTemp) {
result = elementInfo.extraTempLow[extraTemp];
}
}
}
// If result is an array, choose a random item
if (Array.isArray(result)) {
result = result[Math.floor(Math.random() * result.length)];
}
if (result === null) {deletePixel(pixel.x,pixel.y);return false}
else {
if (elements[result].customColor) {
changePixel(pixel,result,false);
pixel.color = color;
}
else if (elementInfo.stateLowColor) {
changePixel(pixel,result,false);
pixel.color = pixelColorPick(pixel,elementInfo.stateLowColor);
}
else if (elementInfo.stateLowColorMultiplier) {
var color = pixel.color;
changePixel(pixel,result,false);
var rgb = color.match(/\d+/g);
var m = elementInfo.stateLowColorMultiplier;
if (Array.isArray(m)) {
m = m[Math.floor(Math.random() * m.length)];
}
var r = Math.floor(rgb[0] * m);
var g = Math.floor(rgb[1] * m);
var b = Math.floor(rgb[2] * m);
// Make sure the color is within the RGB range
r = Math.max(0, Math.min(255, r));
g = Math.max(0, Math.min(255, g));
b = Math.max(0, Math.min(255, b));
pixel.color = "rgb("+r+","+g+","+b+")";
}
else { changePixel(pixel,result,false); }
}
}
return true;
}
function getNeighbors(pixel) {
var neighbors = [];
var x = pixel.x;
var y = pixel.y;
if (!isEmpty(x-1,y,true)) { neighbors.push(pixelMap[x-1][y]); }
if (!isEmpty(x+1,y,true)) { neighbors.push(pixelMap[x+1][y]); }
if (!isEmpty(x,y-1,true)) { neighbors.push(pixelMap[x][y-1]); }
if (!isEmpty(x,y+1,true)) { neighbors.push(pixelMap[x][y+1]); }
return neighbors;
}
function circleCoords(x,y,radius) {
var coords = [];
for (var i = x - radius; i <= x + radius; i++) {
for (var j = y - radius; j <= y + radius; j++) {
if (Math.pow(i-x,2) + Math.pow(j-y,2) <= Math.pow(radius,2)) {
coords.push({x:i,y:j});
}
}
}
return coords;
}
function lineCoords(x1,y1,x2,y2,width) {
// use the coordinates and the width to return a list of coordinates in a pixel line
var coords = [];
var x = x1;
var y = y1;
var dx = Math.abs(x2-x1);
var dy = Math.abs(y2-y1);
var sx = (x1 < x2) ? 1 : -1;
var sy = (y1 < y2) ? 1 : -1;
var err = dx-dy;
while (true) {
coords.push([x,y]);
if (x == x2 && y == y2) { break; }
var e2 = 2*err;
if (e2 > -dy) { err -= dy; x += sx; }
if (e2 < dx) { err += dx; y += sy; }
}
var newcoords = [];
// loop through mouseRange(x,y,width) of each coordinate and add to coords if not already in coords
for (var i = 0; i < coords.length; i++) {
var x = coords[i][0];
var y = coords[i][1];
var range = mouseRange(x,y,width);
for (var j = 0; j < range.length; j++) {
var x2 = range[j][0];
var y2 = range[j][1];
if (!coords.indexOf([x2,y2]) > -1) {
newcoords.push([x2,y2]);
}
}
}
return newcoords;
}
function rectCoords(x1,y1,x2,y2) {
var coords = [];
for (var i = x1; i <= x2; i++) {
for (var j = y1; j <= y2; j++) {
coords.push({x:i,y:j});
}
}
return coords;
}
function drawCirclePixels(x,y,radius) {
var coords = circleCoords(x,y,radius);
for (var i = 0; i < coords.length; i++) {
if (isEmpty(coords[i].x,coords[i].y)) {
createPixel(currentElement,coords[i].x,coords[i].y);
}
}
}
function selection(x1,y1,x2,y2) {
var selection = [];
for (var i = x1; i <= x2; i++) {
selection[i] = [];
for (var j = y1; j <= y2; j++) {
selection[i][j] = pixelMap[i][j];
}
}
return selection;
}
unicodeSkips = {
0: 65, // null -> A
58: 65, // : -> A
91: 97, // [ -> a
123: 192, // { -> À
215: 216, // × -> Ø
247: 248, // ÷ -> ø
688: 880,
884: 886,
888: 891,
894: 895,
896: 902,
903: 904,
907: 908,
909: 910,
930: 931,
1155: 1162,
1328: 1329,
1367: 1376,
1417: 1488,
1514: 12448,
12544: 13312
};
// version;codes;pixels;
basicProperties = ["x","y","color","start","origColor","temp"];
vitalSettings = ["abszero","airdensity","airtemp","bg","burn","clouds","events","stain"];
function uuidv4() {
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
);
}
function generateSave(pixelarray,saveOptions) {
if (!pixelarray) { pixelarray = pixelMap; }
if (!saveOptions) { saveOptions = {}; }
var ignoreProperties = JSON.parse(JSON.stringify(basicProperties));
if (saveOptions.keep) {
for (var i = 0; i < saveOptions.keep.length; i++) {
ignoreProperties.splice(ignoreProperties.indexOf(saveOptions.keep[i]),1);
}
}
pixelarray = JSON.parse(JSON.stringify(pixelarray));
var codes = {};
var codesReverse = {};
var codeN = 65;
for (var i = 0; i < pixelarray.length; i++) {
for (var j = 0; j < pixelarray[i].length; j++) {
var pixel = pixelarray[i][j];
if (pixel) {
var keepColor = false;
if (elements[pixel.element].singleColor || elements[pixel.element].customColor || elements[pixel.element].forceSaveColor) {
keepColor = pixel.color
}
// remove unneeded properties
for (var k = 0; k < ignoreProperties.length; k++) { delete pixel[ignoreProperties[k]]; }
if (keepColor !== false) { pixel.color = keepColor }
if (!saveOptions.raw && pixel.element) {
if (!codes[pixel.element]) {
var char = String.fromCharCode(codeN);
codes[pixel.element] = char;
codesReverse[char] = pixel.element;
codeN++;
if (unicodeSkips[codeN]) {
codeN = unicodeSkips[codeN];
}
}
pixel.element = codes[pixel.element];
}
if (pixel.temp !== undefined) {
pixel.temp = Math.round(pixel.temp);
if (pixel.temp === airTemp) { delete pixel.temp; }
}
if (!saveOptions.raw) {
for (var prop in pixel) {
if (!codes[prop]) {
var char = String.fromCharCode(codeN);
codes[prop] = char;
codesReverse[char] = prop;
codeN++;
if (unicodeSkips[codeN]) {
codeN = unicodeSkips[codeN];
}
}
pixel[codes[prop]] = pixel[prop];
delete pixel[prop];
}
}
}
else {
pixelarray[i][j] = 0;
}
}
}
var userSettings = {};
if (saveOptions.settings !== false) {
for (var key in settings) {
if (vitalSettings.indexOf(key) !== -1) {
userSettings[key] = settings[key];
}
}
}
if (saveOptions.mods === false) { var mods = []; }
else { var mods = enabledMods }
if (window.location.protocol === "file:") {
var url = "";
}
else {
var url = window.location.href;
}
if (!saveOptions.raw) { var compressedMap = JSON.stringify(pixelarray).replace(/,0/g,"×").replace(/":"/g,"»").replace(/,"/g,"§").replace(/element»/g,"©").replace(/"\},\{"/g,"¸").replace(/×××/g,"³").replace(/¸©/g,"¦").replace(/"\}\],\[/g,"®").replace(/\{"/g,"¶").replace(/:true/g,"¥").replace(/:false/g,"¡").replace(/":/g,"¼").replace(/\},/g,"½").replace(/"¥§/g,"¾").replace(/³³³/g,"°").replace(/\],\[/g,"¤").replace(/rgb\(/g,"º").replace(/\)¸/g,"ª"); }
else { var compressedMap = pixelarray; }
var seriesIndex = 0;
var createdTime = Date.now();
var seriesId = uuidv4();
if (currentSaveData) {
if (currentSaveData.seriesIndex !== undefined) {
seriesIndex = currentSaveData.seriesIndex + 1;
}
if (currentSaveData.created) {
createdTime = currentSaveData.created;
}
if (currentSaveData.seriesId) {
seriesId = currentSaveData.seriesId;
}
}
return {
"meta":{
"saveVersion":"sb"+saveVersion,
"gameVersion":currentversion,
"name":saveOptions.name||"",
"desc":saveOptions.desc||"",
"author":saveOptions.author||"",
"created":createdTime,
"updated":Date.now(),
"seriesIndex":seriesIndex,
"uuid":uuidv4(),
"seriesId":seriesId,
"url":url,
},
"saveConfig":{
"settings":userSettings,
"mods":mods,
"pixelTicks":pixelTicks,
"tps":tps,
"currentElement":currentElement,
"height":height,
"width":width,
"pixelSize":pixelSize,
"view":view,
"paused":paused,
"mouseSize":mouseSize,
},
"codes":codesReverse,
"pixelMap":compressedMap
}
}
function loadSave(saveJSON) {
if (!saveJSON.pixelMap) { return }
var compressedMap = saveJSON.pixelMap;
if (!compressedMap) {
alert("Invalid save file - missing pixelMap."); return;
}
var saveConfig = saveJSON.saveConfig || {};
var savePixelSize = saveConfig.pixelSize||6;
var version = parseInt(saveJSON.meta.saveVersion.split("sb")[1]);
if (version < 1 || !version) {
alert("This save was made in an unknown version of Sandboxels, and may not load correctly.")
}
else if (version > saveVersion) {
alert("This save was made in a newer version of Sandboxels, and may not load correctly. Please use the latest version.")
}
resizeCanvas(saveConfig.height*savePixelSize+savePixelSize,saveConfig.width*savePixelSize+savePixelSize,savePixelSize);
clearAll(true);
if (saveConfig.settings) {
for (var key in saveConfig.settings) {
settings[key] = saveConfig.settings[key];
}
}
if (saveConfig.mods) {
var modConfirm = false;
for (var i = 0; i < saveConfig.mods.length; i++) {
if (enabledMods.indexOf(saveConfig.mods[i]) === -1) {
modConfirm = confirm("Install included mods for this save? Only continue if you trust this file's source. They may or may not be necessary.\n\n"+saveConfig.mods.join("\n"));
break;
}
}
if (modConfirm) {
for (var i = 0; i < saveConfig.mods.length; i++) {
if (enabledMods.indexOf(saveConfig.mods[i]) === -1) {
addMod(saveConfig.mods[i],true);
}
}
window.location.reload();
}
}
tps = saveConfig.tps||30;
resetInterval(tps);
if (saveConfig.currentElement) {
selectElement(saveConfig.currentElement||"sand");
selectCategory(elements[currentElement].category);
}
if (saveConfig.mouseSize) { mouseSize = saveConfig.mouseSize };
if (saveConfig.view) { setView(saveConfig.view) };
if (saveConfig.paused && !paused) { togglePause(); }
if (typeof compressedMap !== "object") {
if (version >= 2) {
compressedMap = compressedMap.replace(/ª/g,")¸").replace(/º/g,"rgb(");
}
compressedMap = compressedMap.replace(/¤/g,"],[").replace(/°/g,"³³³").replace(/¾/g,'"¥§').replace(/½/g,'},').replace(/¼/g,'":').replace(/¡/g,":false").replace(/¥/g,":true").replace(/¶/g,'{"').replace(/®/g,'"}],[').replace(/¦/g,"¸©").replace(/³/g,"×××").replace(/¸/g,'"},{"').replace(/©/g,"element»").replace(/§/g,',"').replace(/»/g,'":"').replace(/×/g,",0");
pixelarray = JSON.parse(compressedMap);
}
else {
pixelarray = compressedMap;
}
for (var x = 0; x < pixelarray.length; x++) {
for (var y = 0; y < pixelarray[x].length; y++) {
var pixel = pixelarray[x][y];
if (pixel) {
for (var prop in pixel) {
if (saveJSON.codes[prop]) {
pixel[saveJSON.codes[prop]] = pixel[prop];
delete pixel[prop];
}
if (pixel.element) {
pixel.element = saveJSON.codes[pixel.element]||pixel.element;
if (!elements[pixel.element]) {
pixel.element = "unknown";
}
}
}
createPixel(pixel.element,x,y);
// set the properties
for (var prop in pixel) {
pixelMap[x][y][prop] = pixel[prop];
}
}
else {
pixelarray[x][y] = undefined;
}
}
}
pixelTicks = saveConfig.pixelTicks||0;
currentSaveData = {
"seriesIndex":saveJSON.meta.seriesIndex,
"uuid":saveJSON.meta.uuid,
"seriesId":saveJSON.meta.seriesId,
"created":saveJSON.meta.created,
"name":saveJSON.meta.name,
"author":saveJSON.meta.author,
"desc":saveJSON.meta.desc,
}
if (saveJSON.meta.author) {
logMessage("Created by "+saveJSON.meta.author);
}
return pixelarray;
}
function explodeAt(x,y,radius,fire="fire") {
// if fire contains , split it into an array
if (fire.indexOf(",") !== -1) {
fire = fire.split(",");
}
var coords = circleCoords(x,y,radius);
var power = radius/10;
//for (var p = 0; p < Math.round(radius/10+1); p++) {
for (var i = 0; i < coords.length; i++) {
// damage value is based on distance from x and y
var damage = Math.random() + (Math.floor(Math.sqrt(Math.pow(coords[i].x-x,2) + Math.pow(coords[i].y-y,2)))) / radius;
// invert
damage = 1 - damage;
if (damage < 0) { damage = 0; }
damage *= power;
if (isEmpty(coords[i].x,coords[i].y)) {
// create smoke or fire depending on the damage if empty
if (damage < 0.02) { } // do nothing
else if (damage < 0.2) {
createPixel("smoke",coords[i].x,coords[i].y);
}
else {
// if fire is an array, choose a random item
if (Array.isArray(fire)) {
createPixel(fire[Math.floor(Math.random() * fire.length)],coords[i].x,coords[i].y);
}
else {
createPixel(fire,coords[i].x,coords[i].y);
}
}
}
else if (!outOfBounds(coords[i].x,coords[i].y)) {
// damage the pixel
var pixel = pixelMap[coords[i].x][coords[i].y];
var info = elements[pixel.element];
if (info.hardness) { // lower damage depending on hardness(0-1)
if (info.hardness < 1) {
// more hardness = less damage, logarithmic
damage *= Math.pow((1-info.hardness),info.hardness);
}
else { damage = 0; }
}
if (damage > 0.9) {
if (Array.isArray(fire)) {
var newfire = fire[Math.floor(Math.random() * fire.length)];
}
else {
var newfire = fire;
}
changePixel(pixel,newfire);
continue;
}
else if (damage > 0.25) {
if (info.breakInto !== undefined) {
breakPixel(pixel);
continue;
}
else {
if (Array.isArray(fire)) {
var newfire = fire[Math.floor(Math.random() * fire.length)];
}
else {
var newfire = fire;
}
changePixel(pixel,newfire);
continue;
}
}
if (damage > 0.75 && info.burn) {
pixel.burning = true;
pixel.burnStart = pixelTicks;
}
pixel.temp += damage*radius*power;
pixelTempCheck(pixel);
}
}
}
function breakPixel(pixel) {
if (elements[pixel.element].breakInto === undefined) {return;}
// if it is an array, choose a random item, else just use the value
if (Array.isArray(elements[pixel.element].breakInto)) {
var result = elements[pixel.element].breakInto[Math.floor(Math.random() * elements[pixel.element].breakInto.length)];
}
else {
var result = elements[pixel.element].breakInto;
}
// change the pixel to the result
if (result === null) {
deletePixel(pixel.x,pixel.y);
return;
}
if (elements[pixel.element].breakIntoColor) {
var oldelement = pixel.element;
changePixel(pixel,result);
pixel.color = pixelColorPick(pixel, elements[oldelement].breakIntoColor);
}
else {
changePixel(pixel,result);
}
}
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
const checkForEmptyPixels = function(x,y) {
const empty = [];
for (let a of [-1, 0, 1]) {
for (let b of [-1, 0, 1]) {
if (a == 0 && b == 0) continue;
if (outOfBounds(x + a, y + b)) continue;
if (!pixelMap[x + a][y + b]) empty.push([a, b]);
}
}
return empty;
}
adjacentCoords = [
[0,1],
[0,-1],
[1,0],
[-1,0]
];
squareCoords = [
[0,1],
[0,-1],
[1,0],
[-1,0],
[1,1],
[1,-1],
[-1,1],
[-1,-1]
];
squareCoordsShuffle = squareCoords.slice();
adjacentCoordsShuffle = adjacentCoords.slice();
biCoords = [
[0,1],
[1,0]
];
function drawPixels(forceTick=false) {
// newCurrentPixels = shuffled currentPixels
var newCurrentPixels = currentPixels.slice();
var pixelsFirst = [];
var pixelsLast = [];
if (!paused || forceTick) {
shuffleArray(newCurrentPixels);
}
/*{newCurrentPixels.sort(function(p) { // shuffle the pixels but keep elements[p.element].isGas last
return 0.5 - Math.random();
})} // shuffle the pixels if not paused*/
for (var i = 0; i < newCurrentPixels.length; i++) {
pixel = newCurrentPixels[i];
//if (pixelMap[pixel.x][pixel.y] == undefined || currentPixels.indexOf(pixel) == -1) {continue}
if (pixel.del) {continue}
if (!paused || forceTick) {
if (elements[pixel.element].tick) { // Run tick function if it exists
elements[pixel.element].tick(pixel);
}
if (pixel.del) {continue}
if (elements[pixel.element].behavior) { // Parse behavior if it exists
pixelTick(pixel);
}
};
if (pixel.con) { pixel = pixel.con }
if (elements[pixel.element].isGas || elements[pixel.element].glow) {
pixelsLast.push(pixel);
}
else {
pixelsFirst.push(pixel);
}
}
// Draw the current pixels
// var canvas = document.getElementById("game");
// var ctx = canvas.getContext("2d");
if (!hiding) {
// Clear the canvas
if (!settings["bg"]) {ctx.clearRect(0, 0, canvas.width, canvas.height)}
else {
ctx.fillStyle = settings["bg"];
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
var pixelDrawList = pixelsFirst.concat(pixelsLast);
for (var i = 0; i < pixelDrawList.length; i++) {
pixel = pixelDrawList[i];
if (pixelMap[pixel.x][pixel.y] == undefined) {continue}
if (pixel.con) { pixel = pixel.con }
if (view===null || view===3) {
ctx.fillStyle = pixel.color;
}
else if (view === 2) { // thermal view
var temp = pixel.temp;
if (temp < -50) {temp = -50}
if (temp > 6000) {temp = 6000}
// logarithmic scale, with coldest being 225 (-50 degrees) and hottest being 0 (6000 degrees)
var hue = Math.round(225 - (Math.log(temp+50)/Math.log(6000+50))*225);
if (hue < 0) {hue = 0}
if (hue > 225) {hue = 225}
ctx.fillStyle = "hsl("+hue+",100%,50%)";
}
if (ctx.globalAlpha < 1 && !(elements[pixel.element].isGas || elements[pixel.element].glow)) {
ctx.globalAlpha = 1;
}
if (view === null && ((elements[pixel.element].isGas && elements[pixel.element].glow !== false) || elements[pixel.element].glow)) {
if (ctx.globalAlpha!==0.5) { ctx.globalAlpha = 0.5; }
ctx.fillRect((pixel.x-1)*pixelSize, (pixel.y)*pixelSize, pixelSize*3, pixelSize);
ctx.fillRect((pixel.x)*pixelSize, (pixel.y-1)*pixelSize, pixelSize, pixelSize*3);
}
else { // draw the pixel (default)
ctx.fillRect(pixel.x*pixelSize, pixel.y*pixelSize, pixelSize, pixelSize);
}
if (pixel.charge && view !== 2) { // Yellow glow on charge
if (!elements[pixel.element].colorOn) {
ctx.fillStyle = "rgba(255,255,0,0.5)";
ctx.fillRect(pixel.x*pixelSize, pixel.y*pixelSize, pixelSize, pixelSize);
}
}
}
}
if (ctx.globalAlpha < 1) {
ctx.globalAlpha = 1;
}
if (elements[currentElement].maxSize < mouseSize) {
var mouseOffset = Math.trunc(elements[currentElement].maxSize/2);
}
else {
var mouseOffset = Math.trunc(mouseSize/2);
}
var topLeft = [mousePos.x-mouseOffset,mousePos.y-mouseOffset];
var bottomRight = [mousePos.x+mouseOffset,mousePos.y+mouseOffset];
// Draw a square around the mouse
ctx.strokeStyle = "white";
ctx.strokeRect(topLeft[0]*pixelSize,topLeft[1]*pixelSize,(bottomRight[0]-topLeft[0]+1)*pixelSize,(bottomRight[1]-topLeft[1]+1)*pixelSize);
// draw one transparent pixel in the center
if (settings.precision) {
ctx.fillStyle = "rgba(255,255,255,0.5)";
ctx.fillRect(mousePos.x*pixelSize,mousePos.y*pixelSize,pixelSize,pixelSize);
}
if ((!paused) || forceTick) {pixelTicks++};
}
function tick() {
// If mouseIsDown, do mouseAction
if (mouseIsDown && !shaping) {
mouseAction(null,mousePos.x,mousePos.y);
}
// Get the canvas
// var canvas = document.getElementById("game");
// var ctx = canvas.getContext("2d");
if (!paused && settings.events) {
doRandomEvents();
}
if (!paused && elements[currentElement].perTick) {
elements[currentElement].perTick();
}
drawPixels();
if (shaping) {
if (shaping === 1) { // Draw a white line from shapeStart.x to shapeStart.y
ctx.beginPath();
ctx.strokeStyle = "white";
ctx.lineWidth = 2;
ctx.moveTo(shapeStart.x*pixelSize+pixelSizeHalf, shapeStart.y*pixelSize+pixelSizeHalf);
ctx.lineTo(mousePos.x*pixelSize+pixelSizeHalf, mousePos.y*pixelSize+pixelSizeHalf);
ctx.stroke();
ctx.lineWidth = 1;
}
}
updateStats();
}
currentElement = "sand";
currentColor = "#ff0000";
currentProp = null;
currentPropValue = null;
currentElementProp = null;
storedElement = null;
prevElement = null;
currentSaveData = null;
savingState = null;
mouseIsDown = false;
isMobile = false;
// detect if mobile
if (navigator.userAgent && (navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/webOS/i) || navigator.userAgent.match(/iPhone/i) ||
navigator.userAgent.match(/iPad/i) || navigator.userAgent.match(/iPod/i) || navigator.userAgent.match(/BlackBerry/i) ||
navigator.userAgent.match(/Windows Phone/i))) {
isMobile = true;
}
// detect if macOS
if (settings.invertscroll === undefined && navigator.platform.toUpperCase().indexOf('MAC')>=0) {
settings.invertscroll = true;
}
mouseType = null;
function mouseClick(e) {
if (showingMenu && currentElement != "lookup") {
closeMenu();
return false;
}
mouseIsDown = true;
lastPlace = -100;
if (e.button === 0) {
mouseType = "left";
}
else if (e.button === 2) {
mouseType = "right";
}
else if (e.button === 1) {
mouseType = "middle";
}
else {
mouseType = "left";
}
if ((e.button === 0 || e.touches) && placingImage) {
if (e.touches) { mouseMove(e); }
placeImage();
return false;
}
else if (shiftDown && e.button !== 1 && !((elements[currentElement].tool || elements[currentElement].category==="tools") && mouseType==="left")) {
shaping = 1;
shapeStart = mousePos;
}
if (elements[currentElement].singleColor) {
// choose random item from .color
if (Array.isArray(elements[currentElement].color)) {
currentColor = elements[currentElement].color[Math.floor(Math.random() * elements[currentElement].color.length)];
}
else { currentColor = elements[currentElement].color;}
// convert from rgb(r,g,b) to #rrggbb
// RGBToHex takes an array of integers
if (currentColor.indexOf("rgb") !== -1) {
var rgb = currentColor.match(/\d+/g);
currentColor = RGBToHex([parseInt(rgb[0]),parseInt(rgb[1]),parseInt(rgb[2])]);
}
}
mouseMove(e);
return false;
}
function placeImage(placementX,placementY,scale) {
if (!scale) { scale = mouseSize }
// downscale the <img to mouseSize x mouseSize and draw it
var canvas = document.createElement("canvas");
// set width or height proportional to mouseSize
if (placingImage.width > placingImage.height) {
canvas.width = mouseSize;
canvas.height = Math.round(placingImage.height/placingImage.width*mouseSize);
}
else {
canvas.height = mouseSize;
canvas.width = Math.round(placingImage.width/placingImage.height*mouseSize);
}
var newWidth = canvas.width;
var newHeight = canvas.height;
var ctx = canvas.getContext("2d");
if (settings.imagesmooth === 0) {
ctx.webkitImageSmoothingEnabled = false;
ctx.mozImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
}
ctx.drawImage(placingImage,0,0,newWidth,newHeight);
var newImage = ctx.getImageData(0,0,newWidth,newHeight);
var elem = (settings.imageelem || "wood");
if (!elements[elem] || elements[elem].tool || elements[elem].canPlace===false) { elem = "wood";}
// loop through each pixel in the ImageData
for (var x = 0; x < newWidth; x++) {
for (var y = 0; y < newHeight; y++) {
var i = (y*newWidth+x)*4;
var r = newImage.data[i];
var g = newImage.data[i+1];
var b = newImage.data[i+2];
var a = newImage.data[i+3];
if (a > 0.33) {
// mousePos is the center of the image
var pixelX = (placementX||mousePos.x) - Math.round(newWidth/2) + x+1;
var pixelY = (placementY||mousePos.y) - Math.round(newHeight/2) + y+1;
if (isEmpty(pixelX,pixelY)) {
createPixel(elem,pixelX,pixelY);
pixelMap[pixelX][pixelY].color = pixelColorPick(pixelMap[pixelX][pixelY], RGBToHex([r,g,b]));
}
else if (!outOfBounds(pixelX,pixelY) && (shiftDown || mode === "replace")) {
changePixel(pixelMap[pixelX][pixelY],elem);
pixelMap[pixelX][pixelY].color = pixelColorPick(pixelMap[pixelX][pixelY], RGBToHex([r,g,b]));
}
}
}
}
}
function mouseUp(e) {
mouseIsDown = false;
if (shaping) {
if (shaping === 1) { // Draw a line
mouseAction(null,mousePos.x,mousePos.y,shapeStart);
}
shaping = 0;
shapeStart = null;
}
if (elements[currentElement] && elements[currentElement].onMouseUp) {
elements[currentElement].onMouseUp(e);
}
}
function getMousePos(canvas, evt) {
// If evt.touches is defined, use the first touch
if (evt.touches) {
evt.preventDefault();
evt = evt.touches[0];
isMobile = true;
}
var rect = canvas.getBoundingClientRect();
return {
// Round to nearest pixel
x: Math.round((evt.clientX - rect.left)/pixelSize-0.5),
y: Math.round((evt.clientY - rect.top)/pixelSize-0.5)
};
}
function mouseMove(e) {
if (mouseIsDown && !shaping && !placingImage) {
mouseAction(e);
}
else {
var canvas = document.getElementById("game");
lastPos = mousePos;
mousePos = getMousePos(canvas, e);
}
}
function mouseAction(e,mouseX,mouseY,startPos) {
if (mouseType == "left") { mouse1Action(e,mouseX,mouseY,startPos); }
else if (mouseType == "right") { mouse2Action(e,mouseX,mouseY,startPos); }
else if (mouseType == "middle") { mouseMiddleAction(e,mouseX,mouseY); }
}
mouseSize = 5;
mousePos = {x:0,y:0};
lastPos = mousePos;
lastPlace = -100;
function mouseRange(mouseX,mouseY,size) {
var coords = [];
size = size || mouseSize;
if (elements[currentElement].maxSize < mouseSize) {
var mouseOffset = Math.trunc(elements[currentElement].maxSize/2);
}
else {
var mouseOffset = Math.trunc(size/2);
}
var topLeft = [mouseX-mouseOffset,mouseY-mouseOffset];
var bottomRight = [mouseX+mouseOffset,mouseY+mouseOffset];
// Starting at the top left, go through each pixel
for (var x = topLeft[0]; x <= bottomRight[0]; x++) {
for (var y = topLeft[1]; y <= bottomRight[1]; y++) {
// If the pixel is empty, add it to coords
coords.push([x,y]);
}
}
return coords;
}
function mouse1Action(e,mouseX=undefined,mouseY=undefined,startPos) {
if (currentElement === "erase") { mouse2Action(e,mouseX,mouseY); return; }
else if (currentElement === "pick") { mouseMiddleAction(e,mouseX,mouseY); return; }
// If x and y are undefined, get the mouse position
if (mouseX == undefined && mouseY == undefined) {
// var canvas = document.getElementById("game");
// var ctx = canvas.getContext("2d");
lastPos = mousePos;
mousePos = getMousePos(canvas, e);
var mouseX = mousePos.x;
var mouseY = mousePos.y;
}
var cooldowned = false;
if ((mouseSize===1 || elements[currentElement].maxSize===1) && elements[currentElement].cooldown) {
if (pixelTicks-lastPlace < elements[currentElement].cooldown) {
return;
}
cooldowned = true;
}
lastPlace = pixelTicks;
startPos = startPos || lastPos
if (!(isMobile || (cooldowned && startPos.x===lastPos.x && startPos.y===lastPos.y) || elements[currentElement].tool || elements[currentElement].category==="tools")) {
var coords = lineCoords(startPos.x,startPos.y,mouseX,mouseY);
}
else { var coords = mouseRange(mouseX,mouseY); }
var element = elements[currentElement];
var mixList = [];
// For each x,y in coords
for (var i = 0; i < coords.length; i++) {
var x = coords[i][0];
var y = coords[i][1];
if (currentElement === "mix") {
if (!isEmpty(x,y,true)) {
var pixel = pixelMap[x][y];
if (!(elements[pixel.element].movable !== true || elements[pixel.element].noMix === true) || shiftDown) {
mixList.push(pixel);
}
}
}
else if (currentElement === "shock") {
if (!isEmpty(x,y,true)) {
// One loop that repeats 5 times if shiftDown else 1 time
for (var j = 0; j < (shiftDown ? 5 : 1); j++) {
var pixel = pixelMap[x][y];
var con = elements[pixel.element].conduct;
if (con == undefined) {continue}
if (Math.random() < con) { // If random number is less than conductivity
if (!pixel.charge && !pixel.chargeCD) {
pixel.charge = 1;
if (elements[pixel.element].colorOn) {
pixel.color = pixelColorPick(pixel);
}
}
}
else if (elements[pixel.element].insulate != true) { // Otherwise heat the pixel (Resistance simulation)
pixel.temp += 0.25;
pixelTempCheck(pixel);
}
}
}
}
else if (currentElement === "random" && isEmpty(x, y)) {
// create pixel with random element from "randomChoices" array
currentPixels.push(new Pixel(x, y, randomChoices[Math.floor(Math.random() * randomChoices.length)]));
}
else if (elements[currentElement].tool && !(elements[currentElement].canPlace && isEmpty(x,y))) {
// run the tool function on the pixel
if (!isEmpty(x,y,true)) {
var pixel = pixelMap[x][y];
// if the current element has an ignore property and the pixel's element is in the ignore property, don't do anything
if (elements[currentElement].ignore && elements[currentElement].ignore.indexOf(pixel.element) != -1) {
continue;
}
elements[currentElement].tool(pixel);
}
}
else if (mode === "replace") {
if (outOfBounds(x,y)) {
continue;
}
// Remove pixel at position from currentPixels
var index = currentPixels.indexOf(pixelMap[x][y]);
if (index > -1) {
currentPixels.splice(index, 1);
}
if (currentElement == "random") {
currentPixels.push(new Pixel(x, y, randomChoices[Math.floor(Math.random() * randomChoices.length)]));
}
else {
currentPixels.push(new Pixel(x, y, currentElement));
}
if (elements[currentElement].customColor || elements[currentElement].singleColor) {
pixelMap[x][y].color = pixelColorPick(currentElement,currentColor);
}
if (currentElementProp) {
for (var key in currentElementProp) {
pixelMap[x][y][key] = currentElementProp[key]
}
}
}
else if (isEmpty(x, y)) {
currentPixels.push(new Pixel(x, y, currentElement));
if (elements[currentElement].customColor || elements[currentElement].singleColor) {
pixelMap[x][y].color = pixelColorPick(currentElement,currentColor);
}
if (currentElementProp) {
for (var key in currentElementProp) {
pixelMap[x][y][key] = currentElementProp[key]
}
}
}
}
if (currentElement == "mix") {
// 1. repeat for each pixel in mixList
// 2. choose 2 random pixels and swap their x and y
// 3. remove pixel from mixList
for (var i = 0; i < mixList.length; i++) {
var pixel1 = mixList[Math.floor(Math.random()*mixList.length)];
var pixel2 = mixList[Math.floor(Math.random()*mixList.length)];
swapPixels(pixel1,pixel2);
mixList.splice(mixList.indexOf(pixel1),1);
mixList.splice(mixList.indexOf(pixel2),1);
if (elements[pixel1.element].onMix) {
elements[pixel1.element].onMix(pixel1,pixel2);
}
if (elements[pixel2.element].onMix) {
elements[pixel2.element].onMix(pixel2,pixel1);
}
}
}
}
function mouse2Action(e,mouseX=undefined,mouseY=undefined,startPos) {
// Erase pixel at mouse position
if (mouseX == undefined && mouseY == undefined) {
// var canvas = document.getElementById("game");
// var ctx = canvas.getContext("2d");
lastPos = mousePos;
mousePos = getMousePos(canvas, e);
var mouseX = mousePos.x;
var mouseY = mousePos.y;
}
if (dragStart) {
dragStart = 0;
for (var i = 0; i < draggingPixels.length; i++) {
var pixel = draggingPixels[i];
delete pixel.drag;
}
draggingPixels = null;
}
// If the current element is "pick" or "lookup", coords = [mouseX,mouseY]
if (currentElement == "pick" || currentElement == "lookup") {
var coords = [[mouseX,mouseY]];
}
else if (!isMobile) {
startPos = startPos || lastPos
var coords = lineCoords(startPos.x,startPos.y,mouseX,mouseY);
}
else {
var coords = mouseRange(mouseX,mouseY);
}
// For each x,y in coords
for (var i = 0; i < coords.length; i++) {
var x = coords[i][0];
var y = coords[i][1];
if (!isEmpty(x, y)) {
if (outOfBounds(x,y)) {
continue
}
var pixel = pixelMap[x][y];
delete pixelMap[x][y];
// Remove pixel from currentPixels
for (var j = 0; j < currentPixels.length; j++) {
if (currentPixels[j].x == x && currentPixels[j].y == y) {
currentPixels.splice(j, 1);
break;
}
}
}
}
}
function mouseMiddleAction(e, mouseX=undefined, mouseY=undefined) {
if (mouseX == undefined && mouseY == undefined) {
// var canvas = document.getElementById("game");
// var ctx = canvas.getContext("2d");
lastPos = mousePos;
mousePos = getMousePos(canvas, e);
var mouseX = mousePos.x;
var mouseY = mousePos.y;
}
if (!outOfBounds(mouseX, mouseY)) { e.preventDefault(); }
if (!isEmpty(mouseX, mouseY,true)) {
var pixel = pixelMap[mouseX][mouseY];
selectElement(pixel.element);
selectCategory(elements[pixel.element].category);
if (shiftDown) {
currentElementProp = {};
for (var key in pixel) { currentElementProp[key] = pixel[key] }
delete currentElementProp.x;
delete currentElementProp.y;
}
mouseIsDown = false;
}
}
lastScroll = new Date().getTime();
function wheelHandle(e) {
e.preventDefault();
// check if scroll is within the last 25ms
if (new Date().getTime() - lastScroll < 25) {
return;
}
lastScroll = new Date().getTime();
var deltaY = e.deltaY;
if (settings.invertscroll) {
if (deltaY > 0) { deltaY = 1; }
else { deltaY = -1.5; }
}
else {
if (deltaY < 0) { deltaY = 1; }
else { deltaY = -1.5; }
}
mouseSize += Math.round(deltaY*1.5);
if (mouseSize < 1) { mouseSize = 1; }
if (mouseSize > (height > width ? height : width)) { mouseSize = (height > width ? height : width); }
}
function chooseElementPrompt() {
var e = prompt("Enter the element's ID")
if (!e) { return; }
// replace spaces with underscores
e = e.replace(/ /g, "_");
es = mostSimilarElement(e);
if (es !== null) {
selectElement(es);
selectCategory(elements[es].category);
}
else {
alert("Element \"" + e + "\" not found");
}
}
function togglePause() {
paused = !paused;
if (paused) {
document.getElementById("pauseButton").setAttribute("on","true");
}
else {
document.getElementById("pauseButton").setAttribute("on","false");
}
}
function resetPrompt() {
if (settings.resetwarning===0 || currentPixels.length===0 || confirm('Are you sure you want to clear the whole scene?')) {autoResizeCanvas()};
}
function doFrame() {
if (!paused) {
paused = true;
document.getElementById("pauseButton").setAttribute("on","true");
}
drawPixels(true);
}
function selectElement(element) {
if (!elements[element]) { element = "unknown" }
if (elements[currentElement].onUnselect) {
elements[currentElement].onUnselect();
}
var e1 = document.getElementById("elementButton-"+currentElement);
if (e1 != null) { e1.setAttribute("current","false"); }
prevElement = currentElement;
currentElement = element;
currentElementProp = null;
if (elements[element].customColor) {
// show the colorSelector
document.getElementById("colorSelector").style.display = "block";
}
else {
// hide the colorSelector
document.getElementById("colorSelector").style.display = "none";
}
var e2 = document.getElementById("elementButton-"+element);
if (e2) {
e2.setAttribute("current","true");
// if e2 has the class "notify", remove it
if (e2.classList.contains("notify")) {
e2.classList.remove("notify");
}
}
if (elements[element].onSelect) {
elements[element].onSelect();
}
}
function editDistance(s1, s2) {s1 = s1.toLowerCase();s2 = s2.toLowerCase();var costs = new Array();for (var i = 0; i <= s1.length; i++) {var lastValue = i;for (var j = 0; j <= s2.length; j++) {if (i == 0)costs[j] = j;else {if (j > 0) {var newValue = costs[j - 1];if (s1.charAt(i - 1) != s2.charAt(j - 1))newValue = Math.min(Math.min(newValue, lastValue),costs[j]) + 1;costs[j - 1] = lastValue;lastValue = newValue;}}}if (i > 0)costs[s2.length] = lastValue;}return costs[s2.length];}
function similarity(s1, s2) {var longer = s1;var shorter = s2;if (s1.length < s2.length) {longer = s2;shorter = s1;}var longerLength = longer.length;if (longerLength == 0) {return 1.0;}return (longerLength - editDistance(longer, shorter)) / parseFloat(longerLength);}
function mostSimilarElement(s) {
var max = 0;
var maxElement = "";
for (var e in elements) {
var sim = similarity(e,s);
if (sim > max) {
max = sim;
maxElement = e;
}
if (elements[e].alias && elements[e].alias === s) {
max = 0.99;
maxElement = e;
}
}
if (max < 0.5) { return null }
return maxElement;
}
function selectCategory(category) {
if (!category) { return; }
var categoryButton = document.getElementById("categoryButton-"+category);
if (!categoryButton) {return}
// if categoryButton has the class "notify", remove it
if (categoryButton.classList.contains("notify")) {
categoryButton.classList.remove("notify");
}
var categoryDiv = document.getElementById("category-"+category);
// Show this categoryDiv and hide all others
for (var i = 0; i < categoryButton.parentNode.children.length; i++) {
var e = categoryDiv.parentNode.children[i];
e.style.display = "none";
// Set the categoryButton of categoryDiv's category attribute to current=false
document.getElementById("categoryButton-"+e.getAttribute("category")).setAttribute("current",false);
}
categoryDiv.style.display = "block";
categoryButton.setAttribute("current", true);
}
viewKey = {
2: "thermal",
3: "basic"
}
function setView(n) {
if (n <= 3 && n > 1) { // range of number keys with valid views
view = n;
}
else { // reset view
view = null;
}
}
function centerMouse() {
mousePos = {x:width/2,y:height/2};
}
function handleElementButtonClick() {
if (currentElement === this.getAttribute("element")) {
selectElement("unknown");
}
else {
selectElement(this.getAttribute("element"));
}
}
function createElementButton(element) {
var button = document.createElement("button");
// if the element has the attribute "name", use that as the button's text, otherwise use the element with underscores replaced by spaces
var name = elements[element].name || element;
// button.innerHTML = name.replace(/_/g, " ").replace("."," ").replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}).replace(" ",".").replace(/ /g, "");
var str = name.replace(/_./g, function (match) {return match.toUpperCase();}).replace(/_/g, '');
str = str.charAt(0).toUpperCase() + str.slice(1);
button.innerHTML = str;
//set attribute of element to the element
button.setAttribute("element", element);
button.setAttribute("current", "false");
button.className = "elementButton";
//color of the element
// if the element color is an array, make a gradient background color, otherwise, set the background color to the element color
if (elements[element].color instanceof Array) {
button.style.backgroundImage = "linear-gradient(to bottom right, "+elements[element].color.join(", ")+")";
// choose the middlemost item in array
var colorObject = elements[element].colorObject[Math.floor(elements[element].colorObject.length/2)];
if (elements[element].darkText !== false && (elements[element].darkText || (colorObject.r+colorObject.g+colorObject.b)/3 > 200)) {
button.className += " bright"
}
}
else {
button.style.background = elements[element].color;
var colorObject = elements[element].colorObject;
if (elements[element].darkText !== false && (elements[element].darkText || (colorObject.r+colorObject.g+colorObject.b)/3 > 200)) {
button.className += " bright"
}
}
button.id = "elementButton-" + element;
button.onclick = handleElementButtonClick;
// on right click, show the element's info
button.oncontextmenu = function(e) {
e.preventDefault();
closeMenu();
showInfo(this.getAttribute("element"));
}
if (!elements[element].category) {
elements[element].category = "other";
}
var categoryDiv = document.getElementById("category-"+elements[element].category);
if (categoryDiv === null) {
createCategoryDiv(elements[element].category);
categoryDiv = document.getElementById("category-"+elements[element].category);
categoryDiv.style.display = "none";
}
categoryDiv.appendChild(button);
}
function createCategoryDiv(category) {
categoryButton = document.createElement("button");
categoryButton.id = "categoryButton-"+category;
categoryButton.innerHTML = (lang[category] || category).replace("."," ").replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}).replace(" ",".").replace(/ /g, "");;
categoryButton.className = "categoryButton";
categoryButton.setAttribute("category",category);
categoryButton.onclick = function() {
selectCategory(this.getAttribute("category"));
}
document.getElementById("categoryControls").appendChild(categoryButton);
var categoryDiv = document.createElement("div");
//categoryDiv.innerHTML = "<span class='categoryName'>"+category+"</span>";
categoryDiv.setAttribute("id","category-"+category);
categoryDiv.setAttribute("category",category);
categoryDiv.setAttribute("class","category");
document.getElementById("elementControls").appendChild(categoryDiv);
}
function checkUnlock(element) {
if (elements[element] && elements[element].hidden && !settings.unlocked[element]) {
settings.unlocked[element] = true;
if (settings.unhide === 2) {
createElementButton(element)
var categoryButton = document.querySelector(".categoryButton[current='true']");
var currentCategory = categoryButton.getAttribute("category");
if (currentCategory !== elements[element].category) {
document.getElementById("categoryButton-"+elements[element].category).classList.add("notify");
}
// add notify to the elementButton of the element
document.getElementById("elementButton-"+element).classList.add("notify");
hiddenCount--;
document.getElementById("hiddenCount").innerHTML = hiddenCount;
}
saveSettings();
}
}
worldgentypes = {
// layers: [minimum y from bottom, element, chance per pixel]
"grass": {
layers: [
[0.85, "grass"],
[0.50, "dirt"],
[0.05, "rock"],
[0, "basalt"],
]
},
"flower_field": {
layers: [
[0.90, "grass"],
[0.50, "dirt"],
[0.05, "rock"],
[0, "basalt"],
],
decor: [
["flower_seed", 0.1]
]
},
"wheat_field": {
layers: [
[0.50, "mud"],
[0.25, "rock"],
[0, "basalt"],
],
decor: [
["wheat_seed", 0.25]
],
baseHeight: 0.35
},
"tide_pool": {
layers: [
[0.98, "primordial_soup"],
[0.92, "water"],
[0.50, "sand"],
[0.25, "rock"],
[0, "basalt"],
],
decor: [
["methane", 0.1],
["rain_cloud", 0.75]
],
baseHeight: 0.35,
temperature: 30
},
"dirt": {
layers: [
[0.50, "dirt"],
[0.05, "rock"],
[0, "basalt"],
]
},
"snow": {
layers: [
[0.85, "snow"],
[0.50, "dirt"],
[0.05, "rock"],
[0, "basalt"],
],
decor: [
["pinecone", 0.05],
["snow_cloud", 0.75]
],
baseHeight: 0.25,
temperature: -5
},
"rain": {
layers: [
[0.85, "dirt"],
[0.05, "rock"],
[0, "basalt"],
],
decor: [
["cloud", 1, 2],
["rain_cloud", 1, 7],
["rain_cloud", 1, 10],
["rain_cloud", 1, 13],
["rain_cloud", 1, 15],
],
baseHeight: 0.25
},
"forest": {
layers: [
[0.95, "grass"],
[0.50, "dirt"],
[0.05, "rock"],
[0, "basalt"],
],
decor: [ // [element, chance, distance from top]
["sapling", 0.075],
["bird", 0.025, 10],
],
baseHeight: 0.25
},
"jungle": {
layers: [
[0.95, "grass"],
[0.50, "mud"],
[0.05, "gravel"],
[0, "basalt"],
],
decor: [
["sapling", 0.075],
["bamboo_plant", 0.05],
["frog", 0.05, 10],
["bird", 0.05, 5, ["#ff0000","#00ff00","#00ffff","#0000ff"]],
],
baseHeight: 0.25
},
"taiga": {
layers: [
[0.95, "mud"],
[0.50, "dirt"],
[0.05, "rock"],
[0, "basalt"],
],
decor: [
["pinecone", 0.075],
["snow_cloud", 0.75]
],
baseHeight: 0.25,
temperature: -5
},
"mushrooms": {
layers: [
[0.50, "dirt"],
[0.05, "rock"],
[0, "basalt"],
],
decor: [
["mushroom_spore", 0.075],
],
baseHeight: 0.25
},
"sun": {
layers: [
[0.50, "magma"],
],
decor: [
["cloner", 0.1],
["plasma", 0.3],
["light", 0.5],
["hydrogen", 0.5],
["helium", 0.5],
],
baseHeight: 0.25,
temperature: 5498.85
},
"ocean": {
layers: [
[0.25, "salt_water"],
[0.1, "clay", 0.1],
[0.1, "gravel", 0.2],
[0.1, "wet_sand"],
[0.03, "gravel", 0.5],
[0.03, "rock"],
[0, "basalt"],
],
decor: [
["fish", 0.1, 10],
["snail", 0.01, 10],
["algae", 0.4, 10],
]
},
"rock": {
layers: [
[0, "rock"],
],
baseHeight: 0.33
},
"volcanic": {
layers: [
[0.3, "basalt"],
[0.2, "basalt", 0.5],
[0, "magma"]
],
decor: [
["pyrocumulus", 0.75]
],
baseHeight: 0.4,
temperature: 950
},
"desert": {
layers: [
[0.55, "sand"],
[0.35, "bone", 0.03],
[0.35, "charcoal", 0.03],
[0.30, "dirt"],
[0.05, "rock"],
[0, "basalt"],
],
decor: [ // [element, chance, distance from top]
["cactus", 0.05],
],
temperature: 38,
}
};
function clearAll(skipworldgen) {
currentPixels = [];
pixelMap = [];
currentSaveData = null;
for (var i = 0; i < width; i++) {
pixelMap[i] = [];
for (var j = 0; j < height; j++) {
pixelMap[i][j] = undefined;
}
}
pixelTicks = 0;
if (!skipworldgen && settings["worldgen"] && settings["worldgen"] != "off") {
worldGen(worldgentypes[settings["worldgen"]]);
}
clearLog();
}
function mean(arr) {
var sum = 0;
for (var i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum/arr.length;
}
function generateTerrainHeights(width,heightVariance,complexity) {
// array of (width) 0s
var newHeights = [];
for (var i = 0; i < width; i++) {
newHeights[i] = 0;
}
// do midpoint displacement (complexity) times on newHeights
for (var i = 0; i < complexity; i++) {
var newHeights2 = [];
for (var j = 0; j < width; j++) {
newHeights2[j] = 0;
}
for (var j = 0; j < width; j++) {
var x = j;
var y = newHeights[j];
var y2 = y + Math.random()*heightVariance - heightVariance/2;
newHeights2[x] = y2;
}
newHeights = newHeights2;
}
return newHeights;
}
function worldGen(worldtype) {
var complexity = worldtype.complexity || 20;
var heightVariance = worldtype.heightVariance || 0.5;
var baseHeight = height-(height*(worldtype.baseHeight || 0.5));
var layers = worldtype.layers || {0:"rock"};
var yoffsets = generateTerrainHeights(width,heightVariance,complexity);
// 2D world vertical generator
for (var x = 1; x < width; x++) {
var yoffset = yoffsets[x];
var worldHeight = baseHeight+yoffset;
for (var y = 0; y < height; y++) {
// Change element type based on y, from grass > dirt > rock > basalt
if (y > worldHeight) {
// distance from the bottom of worldHeight
var frombottom = worldHeight-(y-worldHeight);
var element = null;
for (var i in layers) {
var layer = layers[i];
if (layer[0] == 0 && yoffset < 0) {
layer[0] = yoffset;
}
if (frombottom > worldHeight*layer[0] && Math.random() < (layer[2] || 1)) {
if (elements[layer[1]]) {
element = layer[1];
break
}
}
}
if (element) {
createPixel(element,x,y);
if (worldtype.temperature) {
pixelMap[x][y].temp = worldtype.temperature;
}
}
}
}
}
// decor
if (worldtype.decor) {
for (var i = 0; i < worldtype.decor.length; i++) {
var decor = worldtype.decor[i];
var element = decor[0];
var chance = decor[1];
for (var x = 1; x < width; x++) {
var y = decor[2] || 5;
// add or subtract worldtype.decorVariance from y
y += Math.round(Math.random()*(worldtype.decorVariance||2) - (worldtype.decorVariance||2)/2);
if (Math.random() < chance && isEmpty(x,y)) {
createPixel(element,x,y);
if (worldtype.temperature) {
pixelMap[x][y].temp = worldtype.temperature;
}
if (decor[3]) {
pixelMap[x][y].color = pixelColorPick(pixelMap[x][y],decor[3])
}
}
}
}
}
}
randomEvents = {
"falling_pixel": function() {
// random x between 1 and width-1
var x = Math.floor(Math.random()*(width-1))+1;
// random y between 1 and 6
var y = Math.floor(Math.random()*6)+1;
if (isEmpty(x,y)) {
// random element from randomEventChoices.falling_pixel
var element = randomEventChoices.falling_pixel[Math.floor(Math.random()*randomEventChoices.falling_pixel.length)];
// if element is an array, choose a random element from the array
if (Array.isArray(element)) {
element = element[Math.floor(Math.random()*element.length)];
}
createPixel(element,x,y);
}
},
"element_circle": function() {
// random x between 1 and width-1
var x = Math.floor(Math.random()*(width-1))+1;
// random y between 1 and height-1
var y = Math.floor(Math.random()*(height-1))+1;
// random radius between 3 and 7
var radius = Math.floor(Math.random()*4)+3;
// random element from randomEventChoices.element_circle
var element = randomEventChoices.element_circle[Math.floor(Math.random()*randomEventChoices.element_circle.length)];
var coords = circleCoords(x,y,radius);
for (var i = 0; i < coords.length; i++) {
var coord = coords[i];
if (isEmpty(coord.x,coord.y)) {
createPixel(element,coord.x,coord.y);
}
}
},
"explosion": function() {
// similar but do explodeAt(x,y,radius,element)
var x = Math.floor(Math.random()*(width-1))+1;
var y = Math.floor(Math.random()*(height-1))+1;
var radius = Math.floor(Math.random()*4)+3;
var element = randomEventChoices.explosion[Math.floor(Math.random()*randomEventChoices.explosion.length)];
explodeAt(x,y,radius,element);
},
"temperature": function() {
// set the temperature in a random circle to a random value between -200 and 200
var x = Math.floor(Math.random()*(width-1))+1;
var y = Math.floor(Math.random()*(height-1))+1;
var radius = Math.floor(Math.random()*4)+3;
var temp = Math.floor(Math.random()*400)-200;
var coords = circleCoords(x,y,radius);
for (var i = 0; i < coords.length; i++) {
var coord = coords[i];
if (!outOfBounds(coord.x,coord.y) && !isEmpty(coord.x,coord.y)) {
pixelMap[coord.x][coord.y].temp += temp;
}
}
}
}
randomEventChoices = {
"falling_pixel": ["fireball","fallout","seeds",["bomb","cold_bomb"],"human","gold_coin","feather","glitter","homunculus","egg","frozen_frog","sapling","smoke_grenade","party_popper","lightning","frozen_worm","pinecone","cactus","earthquake","tornado"],
"element_circle": ["carbon_dioxide","primordial_soup","fly","steam","oxygen","sugar","bee","firefly","tadpole","flash","foam","bless","liquid_light"],
"explosion": ["fire","cold_fire","methane","electric","light","laser","radiation","plasma","liquid_nitrogen","liquid_helium","liquid_neon","acid_gas","fw_ember","malware",["stench","plague"],["firework","fire","fire"],"bubble","confetti","balloon","dye","bless"]
}
function doRandomEvents() {
var chance = settings.events;
if (Math.random() < chance) {
// run a random function from randomEvents
var event = randomEvents[Object.keys(randomEvents)[Math.floor(Math.random()*Object.keys(randomEvents).length)]];
event();
}
}
shiftDownTypes = {
1: "[↑ ]",
2: "[A ]",
3: "[ ↑]",
4: "[ A]"
}
// Update stats
function updateStats() {
var statsDiv = document.getElementById("stats");
var stats = "<span id='stat-pos' class='stat'>x"+mousePos.x+",y"+mousePos.y+"</span>";
stats += "<span id='stat-pixels' class='stat'>Pxls:" + currentPixels.length+"</span>";
stats += "<span id='stat-tps' class='stat'>" + tps+"tps</span>";
stats += "<span id='stat-ticks' class='stat'>" + pixelTicks+"</span>";
if ((typeof pixelMap).length === 9) { return; }
if (pixelMap[mousePos.x] !== undefined) {
var currentPixel = pixelMap[mousePos.x][mousePos.y];
if (currentPixel !== undefined) {
stats += "<span id='stat-element' class='stat'>Elem:"+(elements[currentPixel.element].name || currentPixel.element).toUpperCase()+"</span>";
stats += "<span id='stat-temperature' class='stat'>Temp:"+formatTemp(currentPixel.temp)+"</span>";
if (currentPixel.charge) {
stats += "<span id='stat-charge' class='stat'>C"+currentPixel.charge+"</span>";
}
if (currentPixel.burning) {
stats += "<span id='stat-burning' class='stat'>Burning</span>";
}
if (elements[currentPixel.element].hoverStat) {
stats += "<span id='stat-hover' class='stat'>"+elements[currentPixel.element].hoverStat(currentPixel)+"</span>";
}
else if (currentPixel.clone) {
stats += "<span id='stat-clone' class='stat'>"+currentPixel.clone.toUpperCase()+"</span>";
}
else if (currentPixel.con && currentPixel.con.element) {
stats += "<span id='stat-clone' class='stat'>"+currentPixel.con.element.toUpperCase()+"</span>";
}
}
}
if (shiftDown) {
stats += "<span id='stat-shift' class='stat'>"+shiftDownTypes[shiftDown]+"</span>";
}
// If the view is not null, show the view in all caps
if (view !== null) {
stats += "<span id='stat-view' class='stat'>"+viewKey[view]+"</span>";
}
statsDiv.innerHTML = stats;
}
function formatTemp(temp) { // temp is Celcius
if (!settings["units"] || settings["units"] === "m") { // Celsius
return Math.round(temp)+"°C"
}
else if (settings["units"] === "i") { // Fahrenheit
return Math.round(temp*1.8+32)+"°F"
}
else if (settings["units"] === "s") { // Kelvin
return Math.round(temp+273.15)+"K"
}
}
function formatDensity(density) { // temp is kg/m3
var digits = 2;
// if the number is more than 2 digits long, round to 0 digits
if (density > 100) { digits = 0; }
else if (density > 10) { digits = 1; }
// default/metric = kg/m3, imperial = lb/ft3, si = g/cm3
if (!settings["units"] || settings["units"] === "m") { // kg/m3
return density.toFixed(digits)+" kgm<sup>3</sup>"
}
else if (settings["units"] === "i") { // lb/ft3
return (density/16.018).toFixed(digits)+" lbft<sup>3</sup>"
}
else if (settings["units"] === "s") { // g/cm3
// round to 2 decimal places
return ((density/10)/100).toFixed(digits)+" gcm<sup>3</sup>"
}
}
showingMenu = false;
function infoLink(l) {
console.log(l)
if (l instanceof Array) {
var newtext = "";
for (var i = 0; i < l.length; i++) {
var element = l[i];
if (!element) { continue }
// add to newtext a span with the element's name and its onclick to showInfo(element)
if (element=="pixels" || element=="itself") { newtext += element+", "}
else if (!elements[element]) { continue }
else { newtext += "<span class='infoLink' onclick='showInfo(\""+element+"\")'>"+(elements[element].name || element).toUpperCase().replace(/_/g," ")+"</span>, ";}
}
// remove the last comma and space
newtext = newtext.substring(0, newtext.length-2);
return newtext
}
else {
if (l === null) { return "air" }
if (l === undefined) { return "[???]" }
if (l=="pixels" || l=="[???]" || l=="itself") {return l}
else {return "<span class='infoLink' onclick='showInfo(\""+l+"\")'>"+l.toUpperCase().replace(/_/g," ")+"</span>";}
}
}
function showInfo(element,back=false) { // this is such a mess please don't look at it
showingMenu = "info";
var infoParent = document.getElementById("infoParent");
infoParent.style.display = "block";
var infoSearch = document.getElementById("infoSearch");
infoSearch.focus();
var infoTitle = document.getElementById("infoTitle");
var infoText = document.getElementById("infoText");
var error = false;
if (element != undefined) {
// replace all spaces with underscores
element = element.replace(/ /g,"_").toLowerCase();
infoSearch.value = element.toUpperCase();
info = elements[element];
if (info) {
infoTitle.innerHTML = info.name || element.replace(/_/g," ");
infoTitle.innerHTML = infoTitle.innerHTML.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
infoText.innerHTML = "";
if (info.hidden && !settings.unlocked[element]) { infoText.innerHTML += "\nYou haven't discovered this yet.\n" }
if (info.color) {
if (!(info.color instanceof Array)) {
infoText.innerHTML += "\nColor: <span style='background-color:"+info.color+"'> </span>";
}
else {
//gradient
var gradient = info.color;
var gradientString = "linear-gradient(to right";
for (var i = 0; i < gradient.length; i++) {
gradientString += ", "+gradient[i]+" "+(i*100/gradient.length)+"%";
}
gradientString += ")";
infoText.innerHTML += "\nColor: <span style='background:"+gradientString+"'> </span>";
}
}
if (info.desc) {
infoText.innerHTML += "\n"+info.desc;
}
else if (info.extraInfo) {
infoText.innerHTML += "\n"+info.extraInfo;
}
var moves = false;
var deletes = [];
var swaps = [];
var creates = [];
var heats = false;
var cools = false;
var clones = false;
var explodes = false;
var sticks = [];
if (info.behavior) {
// for x and y in behavior array
for (var i = 0; i < info.behavior.length; i++) {
for (var j = 0; j < info.behavior[i][1].length; j++) {
var b0 = info.behavior[i][j];
if (!b0) { continue; }
for (var k = 0; k < b0.split(" AND ").length; k++) {
var b = b0.split(" AND ")[k];
// remove everything after %
b = b.split("%")[0];
if (b.indexOf(":") != -1) {
var arg = b.split(":")[1];
}
else { var arg = undefined }
var b = b.split(":")[0];
if (b == "M1" || b == "M2") {
moves = true;
}
else if (b == "DL") {
if (i==1 && j==1) { arg = "itself" }
else if (!arg) { arg = "pixels" }
if (deletes.indexOf(arg) == -1) { deletes = deletes.concat(arg.split(",")); }
}
else if (b == "SW") {
if (!arg) { arg = "pixels" }
if (swaps.indexOf(arg) == -1) { swaps = swaps.concat(arg.split(",")); }
}
else if (b == "CL") {
clones = true;
}
else if (b == "CR" || b == "CH" || b == "LB" || b == "L1" || b == "L2") {
if (!arg) { arg = "[???]" }
else if (arg.indexOf(">") != -1) { arg = arg.split(">")[1]; }
if (creates.indexOf(arg) == -1) { creates = creates.concat(arg.split(",")); }
}
else if (b == "HT") {
heats = true;
}
else if (b == "CO") {
cools = true;
}
else if (b == "ST") {
if (!arg) { arg = "pixels" }
if (sticks.indexOf(arg) == -1) { sticks = sticks.concat(arg.split(",")); }
}
else if (b == "EX") {
explodes = true;
}
}}}}
// make sure deletes, swaps, creates, and sticks have no duplicate items
deletes = deletes.filter(function(item, pos) {return deletes.indexOf(item) == pos;});
swaps = swaps.filter(function(item, pos) {return swaps.indexOf(item) == pos;});
creates = creates.filter(function(item, pos) {return creates.indexOf(item) == pos;});
sticks = sticks.filter(function(item, pos) {return sticks.indexOf(item) == pos;});
if (info.category == "tools" || info.tool) { infoText.innerHTML += "\nTool."}
else {
if (!moves && info.behavior) { infoText.innerHTML += "\nStationary."; }
if (info.category) { infoText.innerHTML += "\nCategory: "+infoLink(info.category)+"."; }
if (info.noMix) { infoText.innerHTML += "\nWon't mix without Shift."; }
if (info.conduct) { infoText.innerHTML += "\nConducts electricity."; }
if (swaps.length > 0) { infoText.innerHTML += "\nMoves through "+infoLink(swaps)+"."; }
if (creates.length > 0) { infoText.innerHTML += "\nMakes "+infoLink(creates)+"."; }
if (clones) { infoText.innerHTML += "\nClones self." }
if (deletes.length > 0) { infoText.innerHTML += "\nDeletes "+infoLink(deletes)+"."; }
if (heats) { infoText.innerHTML += "\nHeats pixels." }
if (cools) { infoText.innerHTML += "\nCools pixels." }
if (sticks.length > 0) { infoText.innerHTML += "\nSticks to "+infoLink(sticks)+"."; }
if (explodes) { infoText.innerHTML += "\nExplodes." }
if (settings["unhide"]!==1 && info.hidden) { infoText.innerHTML += "\nHidden by default."; }
if (info.density != undefined) { infoText.innerHTML += "\nDensity: "+formatDensity(info.density)+"."; }
if (info.tempHigh != undefined) {
infoText.innerHTML += "\nTurns into "+infoLink(info.stateHigh)+" above "+formatTemp(info.tempHigh)+".";
}
if (info.tempLow != undefined) {
infoText.innerHTML += "\nTurns into "+infoLink(info.stateLow)+" below "+formatTemp(info.tempLow)+".";
}
if (info.breakInto === null) {
infoText.innerHTML += "\nDisappears when broken.";
}
else if (info.breakInto != undefined) {
infoText.innerHTML += "\nBreaks into "+infoLink(info.breakInto)+".";
}
if (info.burn != undefined) { infoText.innerHTML += "\nFlammability: "+info.burn+"%."; }
if (info.burnTime != undefined) {
infoText.innerHTML += "\nBurns for "+info.burnTime+" tick";
if (info.burnTime != 1) { infoText.innerHTML += "s"; }
infoText.innerHTML += ".";
}
if (info.burnInto) { infoText.innerHTML += "\nBurns into "+infoLink(info.burnInto)+"."; }
if (info.fireColor) {
if (!(info.fireColor instanceof Array)) {
infoText.innerHTML += "\nFlame Color: <span style='background-color:"+info.fireColor+"'> </span>";
}
else {
//gradient
var gradient = info.fireColor;
var gradientString = "linear-gradient(to right";
for (var i = 0; i < gradient.length; i++) {
gradientString += ", "+gradient[i]+" "+(i*100/gradient.length)+"%";
}
gradientString += ")";
infoText.innerHTML += "\nFlame Color: <span style='background:"+gradientString+"'> </span>";
}
}
if (info.stain) {
if (info.stain < 0) { infoText.innerHTML += "\nCleans stains."; }
else { infoText.innerHTML += "\nStains solids."; }
}
if (info.customColor) { infoText.innerHTML += "\nColor is customizable."; }
}
if (info.reactions) {
infoText.innerHTML += "\nReacts with " + infoLink(Object.keys(info.reactions)) + ".";
}
if (info.related) {
infoText.innerHTML += "\n\n";
var related = info.related;
if (typeof related == "string") {related = [related];}
infoText.innerHTML += "See Also: "+infoLink(related)+".";
}
if (info.alias) {
infoText.innerHTML += "\n\n";
var alias = info.alias;
if (typeof alias == "string") {alias = [alias];}
infoText.innerHTML += "Also known as "+alias.join(", ").toUpperCase()+".";
}
}
else if (categoryList.indexOf(element) !== -1) {
infoTitle.innerHTML = element;
infoTitle.innerHTML = infoTitle.innerHTML.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
var matchingCategory = [];
// loop through all elements, and add to matchingCategory if it matches the category
for (e in elements) {
if (elements[e].category === element) {
matchingCategory.push(e);
}
}
infoText.innerHTML = "\nCategory of "+matchingCategory.length+".\n\n";
// infoLink of each item in matchingCategory on new lines
var temptext = "";
for (var i = 0; i < matchingCategory.length; i++) {
temptext += infoLink(matchingCategory[i]) + "\n";
}
infoText.innerHTML += temptext;
}
else if (element === "") {
infoTitle.innerHTML = "Browse";
infoText.innerHTML = "\n"+infoLink("all")+" • "+infoLink("undiscovered")+" • "+infoLink("discovered")+"\n\n";
var temptext = "";
for (var i = 0; i < categoryList.length; i++) {
temptext += infoLink(categoryList[i]) + "\n";
}
infoText.innerHTML += temptext+infoLink("hidden");
}
else if (element === "undiscovered") {
infoTitle.innerHTML = "Undiscovered";
var temptext = "";
var n = 0;
for (e in elements) {
if (elements[e].hidden && !settings.unlocked[e]) {
temptext += infoLink(e) + "\n";
n++;
}
}
// sort temptext lines alphabetically
temptext = temptext.split("\n"); temptext.sort(); temptext = temptext.join("\n");
infoTitle.innerHTML += " ("+n+")";
if (temptext === "") { temptext = "You discovered everything!\n\nJoin our <a href='https://discord.gg/ejUc6YPQuS'>Discord</a> to stay up to date with updates."; }
infoText.innerHTML = temptext;
}
else if (element === "all") {
infoTitle.innerHTML = "All ("+elementCount+")";
var temptext = "";
for (e in elements) { temptext += infoLink(e) + "\n"; }
// sort temptext lines alphabetically
temptext = temptext.split("\n"); temptext.sort(); temptext = temptext.join("\n");
infoText.innerHTML = temptext;
}
else if (element === "discovered") {
infoTitle.innerHTML = "Discovered";
var temptext = "";
var n = 0;
for (e in elements) {
if (!elements[e].hidden || settings.unlocked[e]) {
temptext += infoLink(e) + "\n";
n++;
}
}
// sort temptext lines alphabetically
temptext = temptext.split("\n"); temptext.sort(); temptext = temptext.join("\n");
infoTitle.innerHTML += " ("+n+")";
infoText.innerHTML = temptext;
}
else if (element === "hidden") {
infoTitle.innerHTML = "Hidden ("+hiddenCount+")";
var temptext = "";
for (e in elements) {
if (elements[e].hidden) { temptext += infoLink(e) + "\n"; }
}
// sort temptext lines alphabetically
temptext = temptext.split("\n"); temptext.sort(); temptext = temptext.join("\n");
if (temptext === "") { temptext = "You discovered everything!\n\nJoin our <a href='https://discord.gg/ejUc6YPQuS'>Discord</a> to stay up to date with updates."; }
infoText.innerHTML = temptext;
}
else if (element === "air") {
infoTitle.innerHTML = "Air";
infoText.innerHTML = "\nColor: <span> </span>\nCategory: "+infoLink("gases")+".\nDensity: "+formatDensity(airDensity)+"."
}
else {
infoTitle.innerHTML = "";
infoText.innerHTML = "";
error = true;
}
}
else {
infoTitle.innerHTML = "";
infoText.innerHTML = "";
}
infoText.innerHTML += "\n\n\n\n";
if (error) { infoSearch.style.backgroundColor = "rgb(100, 33, 33)"; }
else {
infoSearch.style.backgroundColor = "rgb(66, 66, 66)";
if (!back && infoHistory[infoHistory.length-1] !== element) {infoHistory.push(element);}
}
if (infoHistory.length > 1) {
document.getElementById("infoBackButton").style.display = "inline-block";
}
else {
document.getElementById("infoBackButton").style.display = "none";
}
}
infoHistory = [];
function infoBack() {
if (infoHistory.length > 0) {
infoHistory.pop()
showInfo(infoHistory[infoHistory.length-1], true);
}
}
function closeMenu() {
if (!showingMenu) { return; }
if (showingMenu == "info") {
var infoParent = document.getElementById("infoParent");
var infoSearch = document.getElementById("infoSearch");
infoParent.style.display = "none";
infoSearch.value = "";
showingMenu = false;
infoHistory = [];
}
else if (showingMenu == "mods") {
var modParent = document.getElementById("modParent");
var modManagerUrl = document.getElementById("modManagerUrl");
modParent.style.display = "none";
modManagerUrl.value = "";
showingMenu = false;
}
else if (showingMenu == "saves") {
var savesParent = document.getElementById("savesParent");
savesParent.style.display = "none";
showingMenu = false;
}
else if (showingMenu == "savePrompt") {
var savePrompt = document.getElementById("savePromptParent");
savePrompt.style.display = "none";
showingMenu = false;
savingState = null;
}
else if (showingMenu == "settings") {
var settingsParent = document.getElementById("settingsParent");
settingsParent.style.display = "none";
showingMenu = false;
}
else {
// do it to all elements with the class "menuParent"
var menuParents = document.getElementsByClassName("menuParent");
for (var i = 0; i < menuParents.length; i++) {
menuParents[i].style.display = "none";
}
showingMenu = false;
}
}
function showModManager() {
var modParent = document.getElementById("modParent");
var modManagerUrl = document.getElementById("modManagerUrl");
modParent.style.display = "block";
modManagerUrl.focus();
showingMenu = "mods";
}
function addMod(url,noMessage) {
// remove trailing slashes
while (url.charAt(url.length-1) == "/") { url = url.substring(0, url.length-1); }
// if the mod is in enabledMods, return
for (var i = 0; i < enabledMods.length; i++) {
if (enabledMods[i] == url) { return; }
}
// if the url doesn't have a slash or a dot, alert
if (url.indexOf("/") == -1 && url.indexOf(".") == -1) {
alert("Invalid mod URL.");
return;
}
// if the url doesn't start with http, add "mods/" to the beginning
if (url.indexOf("http") == -1 && url.indexOf("mods/") == -1) { url = "mods/"+url; }
// add it to enabledMods and set the localStorage
enabledMods.push(url);
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
// add to modManagerList
var modManagerList = document.getElementById("modManagerList");
var modName = url.split("/").pop();
modManagerList.innerHTML += "<li><a href='" + url + "' target='_blank'>" + modName + "</a> <span class='removeModX' onclick='removeMod(\"" + url + "\")'>X</span></li>";
document.getElementById("noMods").style.display = "none";
if (!noMessage) { alert("Added mod. Refresh the page to see changes."); }
}
function removeMod(url) {
// remove url from enabledMods and set the localStorage
for (var i = 0; i < enabledMods.length; i++) {
if (enabledMods[i] == url) {
enabledMods.splice(i, 1);
break;
}
}
if (enabledMods.length === 0) {
document.getElementById("noMods").style.display = "block";
}
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
// remove from modManagerList by href
var modManagerList = document.getElementById("modManagerList");
var modManagerListLinks = modManagerList.getElementsByTagName("a");
for (var i = 0; i < modManagerListLinks.length; i++) {
if (modManagerListLinks[i].href.endsWith(url)) {
modManagerListLinks[i].parentNode.remove();
break;
}
}
alert("Removed mod. Refresh the page to see changes.");
}
function showSaves() {
var savesParent = document.getElementById("savesParent");
var saveSlotList = document.getElementById("saveSlotList");
saveSlotList.innerHTML = "";
// loop 12 times, checking if local storage SandboxelsSaves/x exists
// <span class="saveSlot">Slot 1 <span disabled="true">Clear</span> <span disabled="true">Load</span> <span onclick="saveSlot(2)">Save</span></span>
// <span class="saveSlot">Unnamed <span onclick="clearSlot(2)">Clear</span> <span onclick="loadSlot(2)">Load</span> <span onclick="saveSlot(2)">Save</span></span>
for (var i = 1; i < 13; i++) {
var save = localStorage.getItem("SandboxelsSaves/"+i);
var name = "Slot "+i;
if (save) {
name = JSON.parse(save).meta.name || "Unnamed";
name = name.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/"/g, "&quot;");
// truncate
if (name.length > 16) { name = name.substring(0,16)+"..."; }
saveSlotList.innerHTML += "<span id='saveSlot"+i+"' data-name='"+name+"' class='saveSlot'><span class='saveSlotName'>"+name+"</span> <span onclick='clearSlot("+i+")' class='saveOption'>Clear</span> <span onclick='loadSlot("+i+")' class='saveOption'>Load</span> <span onclick='saveSlot("+i+")' class='saveOption'>Save</span></span>";
}
else {
saveSlotList.innerHTML += "<span id='saveSlot"+i+"' data-name='"+name+"' class='saveSlot'><span class='saveSlotName'>"+name+"</span> <span disabled='true' class='saveOption'>Clear</span> <span disabled='true' class='saveOption'>Load</span> <span onclick='saveSlot("+i+")' class='saveOption'>Save</span></span>";
}
}
savesParent.style.display = "block";
showingMenu = "saves";
}
function saveSlot(i) {
savingState = {slot:i};
document.getElementById("saveName").value = document.getElementById("saveSlot"+i).getAttribute("data-name") || "Slot "+i;
showSavePrompt();
}
function loadSlot(i) {
var save = localStorage.getItem("SandboxelsSaves/"+i);
if (save) {
loadSave(JSON.parse(save));
closeMenu();
}
}
function clearSlot(i) {
if (!confirm("Are you sure you want to erase this save slot?")) { return }
localStorage.removeItem("SandboxelsSaves/"+i);
showSaves();
}
function confirmSave() {
if (!savingState) { return }
var saveName = document.getElementById("saveName").value || "Unnamed";
var saveTemp = document.getElementById("saveTemp").getAttribute("state") === "1";
var saveColors = document.getElementById("saveColors").getAttribute("state") === "1";
var saveMods = document.getElementById("saveMods").getAttribute("state") === "1";
var saveSettings = document.getElementById("saveSettings").getAttribute("state") === "1";
var saveRaw = document.getElementById("saveRaw").getAttribute("state") === "1";
var saveAuthor = document.getElementById("saveAuthor").value || "";
if (saveAuthor && !currentSaveData) {
setSetting("authorName",saveAuthor)
}
var saveDesc = document.getElementById("saveDesc").value || "";
var config = {name:saveName,temp:saveTemp,mods:saveMods,settings:saveSettings,raw:saveRaw,keep:[],author:saveAuthor,desc:saveDesc};
if (saveTemp) { config.keep.push("temp") }
if (saveColors) { config.keep.push("color") }
if (savingState.slot) {
// save stringified generateSave() to localStorage SandboxelsSaves/i
localStorage.setItem("SandboxelsSaves/"+savingState.slot, JSON.stringify(generateSave(undefined,config)));
closeMenu();
showSaves();
}
else {
// save to <name>.sbxls
var save = generateSave(undefined,config);
var blob = new Blob([JSON.stringify(save)], {type: "application/json"});
var url = URL.createObjectURL(blob);
var a = document.createElement("a");
a.href = url;
a.download = saveName+".sbxls";
document.body.appendChild(a);
a.click();
setTimeout(function() {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 0);
closeMenu();
}
}
function saveToFile() {
savingState = {slot:null};
document.getElementById("saveName").value = "";
document.getElementById("saveAuthor").value = "";
document.getElementById("saveDesc").value = "";
showSavePrompt();
}
function loadFromFile() {
var input = document.createElement("input");
input.type = "file";
// input.accept = ".sbxls,.json,.txt,text/*,application/json";
input.addEventListener("change", function(e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.readAsText(file,"UTF-8");
reader.onload = readerEvent => {
var content = readerEvent.target.result;
loadSave(JSON.parse(content));
}
closeMenu();
});
input.click();
}
function showSavePrompt() {
closeMenu();
var savePromptParent = document.getElementById("savePromptParent");
var saveWarning = document.getElementById("saveWarning");
if (currentSaveData) {
document.getElementById("saveName").value = currentSaveData.name || "";
document.getElementById("saveAuthor").value = currentSaveData.author || "";
document.getElementById("saveDesc").value = currentSaveData.desc || "";
}
else if (settings.authorName) {
document.getElementById("saveAuthor").value = settings.authorName;
}
saveWarning.innerHTML = "<br>"
var menuTitle = document.querySelector("#savePromptMenu .menuTitle");
if (savingState.slot === null) {
menuTitle.innerHTML = "Save to File";
}
else {
menuTitle.innerHTML = "Save to Slot";
if (localStorage["SandboxelsSaves/"+savingState.slot]) {
saveWarning.innerHTML += "<br>This will overwrite the save in slot "+savingState.slot+"!";
}
}
var saveMods = document.getElementById("saveMods");
if (enabledMods.length !== 0) {
saveMods.style.display = "inline-block";
saveWarning.innerHTML += "<br>Mods might not be necessary to include, and may annoy the user!";
}
else { saveMods.style.display = "none"; }
savePromptParent.style.display = "block";
showingMenu = "savePrompt";
document.getElementById("saveName").focus();
}
function showSettings() {
var settingsParent = document.getElementById("settingsParent");
settingsParent.style.display = "block";
showingMenu = "settings";
}
function setSetting(setting,value) {
settings[setting] = value;
saveSettings();
}
function toggleInput(input,setting,updateText) {
if (input.getAttribute("state") === "0") {
input.setAttribute("state","1");
if (updateText !== false) { input.value = "ON"; }
if (setting) { setSetting(setting,1); }
}
else {
input.setAttribute("state","0");
if (updateText !== false) { input.value = "OFF"; }
if (setting) { setSetting(setting,0); }
}
}
shiftDown = 0;
shaping = 0;
shapeStart = null;
placingImage = null;
dragStart = 0;
draggingPixels = null;
hiding = false;
// On window load, run tick() 20 times per second
tps = 30;
tickInterval = window.setInterval(tick, 1000/tps);
function resetInterval(newtps=30) {
window.clearInterval(tickInterval);
tickInterval = window.setInterval(tick, 1000/newtps);
}
pixelTicks = 0;
mode = null;
view = null;
if (settings.view) {
setView(settings.view)
}
paused = false;
function focusGame() { document.getElementById("game").focus(); if(showingMenu) { closeMenu(); } }
//on window load
gameCanvas = null;
canvas = null;
ctx = null;
window.onload = function() {
// If the browser is Firefox, set #categoryControls padding-bottom:11px;
if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
document.getElementById("categoryControls").style.paddingBottom = "11px";
}
// Loop through runAfterLoadList and run each function
for (var i = 0; i < runAfterLoadList.length; i++) {
runAfterLoadList[i]();
}
// Unknown fallback element
elements.unknown = {
hidden: true,
tool: function(){},
canPlace: false,
excludeRandom: true,
"desc": "Fallback for invalid elements."
}
// Loop through behaviors and each behavior, if it is a string, split the items and replace the value with the array
for (var behavior in behaviors) {
if (typeof behaviors[behavior][0] === "string") {
var newbehavior = [];
for (var i = 0; i < behaviors[behavior].length; i++) {
newbehavior.push(behaviors[behavior][i].split("|"));
}
behaviors[behavior] = newbehavior;
}
}
// convert every color in the elements object to rgb
for (var key in elements) {
if (elements.hasOwnProperty(key)) {
// if the element has no color, skip it
if (elements[key].color === undefined) {
continue;
}
// if the color is an array, loop over each one
if (elements[key].color instanceof Array) {
var rgbs = [];
var rgbos = [];
for (var i = 0; i < elements[key].color.length; i++) {
var c = elements[key].color[i];
if (c.startsWith("#")) {
var rgb = hexToRGB(c);
rgbs.push("rgb("+rgb.r+","+rgb.g+","+rgb.b+")");
rgbos.push(rgb);
}
else {
rgbs.push(c);
}
}
elements[key].color = rgbs;
elements[key].colorObject = rgbos;
} else {
// if elements[key].color starts with #
if (elements[key].color.startsWith("#")) {
var rgb = hexToRGB(elements[key].color);
elements[key].color = "rgb("+rgb.r+","+rgb.g+","+rgb.b+")";
elements[key].colorObject = rgb;
}
}
}
}
autoElements = {
"molten": { // Solid -> Liquid
rgb: [ [2,1.25,0.5], [2,1,0.5], [2,0.75,0] ],
behavior: behaviors.MOLTEN,
type: "high",
viscosity: 10000,
hidden: true,
state: "liquid",
tempDiff: -100
},
"frozen": { // Liquid -> Solid
rgb: [ [1.2,1.2,1.3] ],
behavior: behaviors.WALL,
type: "low",
hidden: true,
state: "solid"
},
"condense": { // Gas -> Liquid
rgb: [ [0.5,0.5,0.5] ],
behavior: behaviors.LIQUID,
type: "low",
hidden: true,
state: "liquid"
},
"vaporize": { // Liquid -> Gas
rgb: [ [1.5,1.5,1.5] ],
behavior: behaviors.GAS,
type: "high",
hidden: true,
state: "gas"
}
}
// Automatic molten element generation
function autoGen(newname,element,autoType) {
var autoInfo = autoElements[autoType];
var newcolor = elements[element].colorObject;
var colorList = [];
var colorObjectList = [];
// if newcolor is not an array, put it in an array
if (!(newcolor instanceof Array)) { newcolor = [newcolor]; }
// for every color in the newcolor array, add a new color with the same value, but with the r and g values increased
for (var i = 0; i < newcolor.length; i++) {
var c = newcolor[i];
for (var j = 0; j < autoInfo.rgb.length; j++) {
var newc = autoInfo.rgb[j];
r = Math.floor(c.r * newc[0]);
g = Math.floor(c.g * newc[1]);
b = Math.floor(c.b * newc[2]);
if (r > 255) {r = 255;} if (g > 255) {g = 255;}
colorList.push("rgb("+r+","+g+","+b+")");
colorObjectList.push({r:r,g:g,b:b});
}
}
var newelem = {
//"name": newname.replaceAll("_"," "),
behavior: autoInfo.behavior,
hidden: autoInfo.hidden || false,
state: autoInfo.state || "solid",
category: autoInfo.category || "states"
}
if (colorList.length <= 1) { colorList = colorList[0]; }
if (colorObjectList.length <= 1) { colorObjectList = colorObjectList[0]; }
newelem.color = colorList;
newelem.colorObject = colorObjectList;
var multiplier = 1.1;
if (autoInfo.type === "high") {
if (!elements[element].stateHigh) {elements[element].stateHigh = newname;}
newelem.temp = elements[element].tempHigh;
newelem.tempLow = elements[element].tempHigh+(autoInfo.tempDiff || 0);
newelem.stateLow = element;
// Change density by *0.9
if (elements[element].density) { newelem.density = Math.round(elements[element].density * 0.9 * 10) / 10; }
}
else if (autoInfo.type === "low") {
if (!elements[element].stateLow) {elements[element].stateLow = newname;}
newelem.temp = elements[element].tempLow;
newelem.tempHigh = elements[element].tempLow+(autoInfo.tempDiff || 0);
newelem.stateHigh = element;
multiplier = 0.5;
// Change density by *1.1
if (elements[element].density) { newelem.density = Math.round(elements[element].density * 1.1 * 10) / 10; }
}
if (!elements[element].ignore) { elements[element].ignore = [] }
elements[element].ignore.push(newname);
if (elements[element].viscosity || autoInfo.viscosity) {
newelem.viscosity = elements[element].viscosity || autoInfo.viscosity;
}
// Change by *multiplier
if (elements[element].conduct) { newelem.conduct = Math.round(elements[element].conduct * multiplier * 10) / 10; }
if (elements[element].burn) { newelem.burn = Math.min(100,Math.round(elements[element].burn * multiplier * 10) / 10); }
if (elements[element].burnTime) { newelem.burnTime = Math.round(elements[element].burnTime * multiplier * 10) / 10; }
if (elements[element].burnInto) { newelem.burnInto = elements[element].burnInto; }
if (elements[element].fireColor) { newelem.fireColor = elements[element].fireColor; }
// If the new element doesn't exist, add it
if (!elements[newname]) { elements[newname] = newelem; }
else {
// Loop through newelem's keys and values, copy them to the new element if they are not already defined
for (var key in newelem) {
if (elements[newname][key] == undefined) { elements[newname][key] = newelem[key]; }
}
}
if (autoType === "molten" && (elements.molten_slag && elements.molten_slag.ignore && elements.molten_slag.ignore.indexOf(element) === -1)) { // Slag reactions
if (newname !== "molten_slag") {
if (!elements[newname].reactions) { elements[newname].reactions = {}; }
elements[newname].reactions.ash = { elem1:null, elem2:"molten_slag" };
elements[newname].reactions.dust = { elem1:null, elem2:"molten_slag" };
elements[newname].reactions.magma = { elem1:null, elem2:"molten_slag" }
elements[newname].reactions.smog = { elem1:null, elem2:"molten_slag" }
elements[newname].reactions.pyrocumulus = { elem1:null, elem2:"molten_slag" }
elements[newname].reactions.dioxin = { elem1:null, elem2:"molten_slag" }
elements[newname].reactions.poison_gas = { elem1:null, elem2:"molten_slag" }
elements[newname].reactions.dirt = { elem1:null, elem2:"molten_slag" }
elements[newname].reactions.molten_dirt = { elem1:null, elem2:"molten_slag" }
};
}
}
// Loop through each element. If it has a tempHigh, but not a stateHigh, create a new molten element
for (element in elements) {
if (elements[element].tempHigh!==undefined && (elements[element].stateHigh===undefined||elements[element].forceAutoGen)) {
var newname = elements[element].stateHighName;
if ((elements[element].state==="solid" || !elements[element].state)) { // Melting
if (!newname) { newname = "molten_"+element }
autoGen(newname,element,"molten");
}
else if (elements[element].state==="liquid") { // Evaporating
if (!newname) {
newname = element;
if (newname.startsWith("liquid_")) { newname = newname.substring(7); }
if (newname.startsWith("molten_")) { newname = newname.substring(7); }
newname += "_gas";
}
autoGen(newname,element,"vaporize");
}
}
if (elements[element].tempLow!==undefined && (elements[element].stateLow===undefined||elements[element].forceAutoGen)) {
var newname = elements[element].stateLowName;
if (elements[element].state==="liquid") { // Freezing
if (!newname) {
newname = element;
if (newname.startsWith("liquid_")) { newname = newname.substring(7); }
if (newname.endsWith("_water")) { newname = newname.substring(0,newname.length-6); }
newname += "_ice";
}
autoGen(newname,element,"frozen");
}
else if (elements[element].state==="gas") { // Condensing
if (!newname) {
newname = element;
if (newname.endsWith("_gas")) { newname = newname.substring(0,newname.length-4); }
newname = "liquid_"+newname;
}
autoGen(newname,element,"condense");
}
}
if (elements[element].behavior && typeof elements[element].behavior[0] === "string") {
var newbehavior = [];
for (var i = 0; i < elements[element].behavior.length; i++) {
newbehavior.push(elements[element].behavior[i].split("|"));
}
elements[element].behavior = newbehavior;
}
if (elements[element].behaviorOn && typeof elements[element].behaviorOn[0] === "string") {
var newbehavior = [];
for (var i = 0; i < elements[element].behaviorOn.length; i++) {
newbehavior.push(elements[element].behaviorOn[i].split("|"));
}
elements[element].behaviorOn = newbehavior;
}
}
// Loop through runAfterAutogenList and run each function
for (var i = 0; i < runAfterAutogenList.length; i++) {
runAfterAutogenList[i]();
}
// Loop through each element, final checks
nextid = 1;
for (key in elements) {
elements[key].id = nextid;
nextid++;
// Language Loader Part 2
if (lang[key] !== undefined) {
elements[key].name = lang[key]
}
// If the element has no behavior, set it to behaviors.WALL
if (!elements[key].behavior && !elements[key].tick) {
elements[key].tick = function(pixel) {};
}
// If the behavior is a function, delete it and set tick to it instead
if (typeof elements[key].behavior === "function") {
if (elements[key].tick) {
elements[key].tick1 = elements[key].tick;
elements[key].tick2 = elements[key].behavior;
elements[key].tick = function(pixel) {
if (pixel.start === pixelTicks) {return}
var id = elements[pixel.element].id;
elements[pixel.element].tick1(pixel);
if (!pixel.del && id === elements[pixel.element].id) {
elements[pixel.element].tick2(pixel);
}
}
}
else {
elements[key].tick = elements[key].behavior;
}
delete elements[key].behavior;
}
// If the element has no color, set it to white
if (elements[key].color === undefined) {
elements[key].color = "rgb(255,255,255)";
elements[key].colorObject = {r:255,g:255,b:255};
}
if (elements[key].movable === undefined) {
// If the element's behavior is an array and contains M1 or M2, set its movable to true
if (elements[key].behavior && typeof elements[key].behavior[0] === "object") {
var bstring = JSON.stringify(elements[key].behavior);
if (bstring.indexOf("M1")!==-1 || bstring.indexOf("M2")!==-1) { elements[key].movable = true; }
}
if (elements[key].tick) { elements[key].movable = true; }
}
if (elements[key].behavior) {
// If the element's behavior[1][1] includes "FX", set it's flippableX to true
if (elements[key].behavior[1][1].indexOf("FX") !== -1) {
elements[key].flippableX = true;
}
// If the element's behavior[1][1] includes "FY", set it's flippableY to true
if (elements[key].behavior[1][1].indexOf("FY") !== -1) {
elements[key].flippableY = true;
}
// If the element's behavior stringified includes "BO", loop through the behavior
if (elements[key].behavior.toString().indexOf("BO") !== -1 && !elements[key].rotatable) {
for (var i = 0; i < elements[key].behavior.length; i++) {
// Loop through each array in the behavior
for (var j = 0; j < elements[key].behavior[i].length; j++) {
// If the behavior includes "BO", set the behaviorOn to the behavior
if (elements[key].behavior[i][j].indexOf("BO") !== -1) {
if ((i==0 && j==0) || (i==0 && j==2) || (i==2 && j==0) && (i==2 && j==2)) {
elements[key].flippableX = true;
elements[key].flippableY = true;
}
else if (i==0 || i==2) {
elements[key].flippableY = true;
}
else if (j==0 || j==2) {
elements[key].flippableX = true;
}
}
}
}
}
// If the element's behavior[1][1] includes "RT", set it's rotatable to "true"
if (elements[key].behavior[1][1].indexOf("RT") !== -1) {
elements[key].rotatable = true;
}
}
// If the element's state is "gas", isGas = true
if (elements[key].state === "gas") {
elements[key].isGas = true;
}
// Else if the state is not "solid" or "liquid", delete it
else if (elements[key].state !== "solid" && elements[key].state !== "liquid") {
delete elements[key].state;
}
// If the element has reactions, loop through each one (it is an object), if the value for elem1 or elem2 is not an element and is not null, remove that key
if (elements[key].reactions) {
for (var reaction in elements[key].reactions) {
// If elem1 exists
if (elements[key].reactions[reaction].elem1) {
// If elem1 is an array, loop through each element, else check once. Don't delete if it === null
if (Array.isArray(elements[key].reactions[reaction].elem1)) {
for (var i = 0; i < elements[key].reactions[reaction].elem1.length; i++) {
if (elements[key].reactions[reaction].elem1[i] && !elements[elements[key].reactions[reaction].elem1[i]]) {
elements[key].reactions[reaction].elem1.splice(i,1);
}
}
}
else if (elements[key].reactions[reaction].elem1 && !elements[elements[key].reactions[reaction].elem1]) {
delete elements[key].reactions[reaction].elem1;
}
}
// If elem2 exists
if (elements[key].reactions[reaction].elem2) {
// If elem2 is an array, loop through each element, else check once. Don't delete if it === null
if (Array.isArray(elements[key].reactions[reaction].elem2)) {
for (var i = 0; i < elements[key].reactions[reaction].elem2.length; i++) {
if (elements[key].reactions[reaction].elem2[i] && !elements[elements[key].reactions[reaction].elem2[i]]) {
elements[key].reactions[reaction].elem2.splice(i,1);
}
}
}
else if (elements[key].reactions[reaction].elem2 && !elements[elements[key].reactions[reaction].elem2]) {
delete elements[key].reactions[reaction].elem2;
}
}
}
}
// If the element's stateHigh or stateLow is not an element, remove it and tempHigh/Low
if (elements[key].stateHigh) {
// If it's an array, do it for each item, otherwise, just do it once
if (Array.isArray(elements[key].stateHigh)) {
for (var i = 0; i < elements[key].stateHigh.length; i++) {
if (!elements[elements[key].stateHigh[i]] && elements[key].stateHigh[i] !== null) {
elements[key].stateHigh.splice(i,1);
}
}
if (elements[key].stateHigh.length == 0) {
delete elements[key].stateHigh;
delete elements[key].tempHigh;
}
}
else {
if (!elements[elements[key].stateHigh] && elements[key].stateHigh !== null) {
delete elements[key].stateHigh;
delete elements[key].tempHigh;
}
}
}
if (elements[key].stateLow) {
if (Array.isArray(elements[key].stateLow)) {
for (var i = 0; i < elements[key].stateLow.length; i++) {
if (!elements[elements[key].stateLow[i]] && elements[key].stateLow[i] !== null) {
elements[key].stateLow.splice(i,1);
}
}
if (elements[key].stateLow.length == 0) {
delete elements[key].stateLow;
delete elements[key].tempLow;
}
}
else {
if (!elements[elements[key].stateLow] && elements[key].stateLow !== null) {
delete elements[key].stateLow;
delete elements[key].tempLow;
}
}
}
// same for burnInto
if (elements[key].burnInto) {
if (Array.isArray(elements[key].burnInto)) {
for (var i = 0; i < elements[key].burnInto.length; i++) {
if (!elements[elements[key].burnInto[i]]) {
delete elements[key].burnInto[i];
}
}
if (elements[key].burnInto.length == 0) {
delete elements[key].burnInto;
}
}
else {
if (!elements[elements[key].burnInto]) {
delete elements[key].burnInto;
}
}
}
// same for breakInto
if (elements[key].breakInto) {
if (Array.isArray(elements[key].breakInto)) {
for (var i = 0; i < elements[key].breakInto.length; i++) {
if (elements[key].breakInto[i]!==null && !elements[elements[key].breakInto[i]]) { delete elements[key].breakInto[i]; }
}
if (elements[key].breakInto.length == 0) { delete elements[key].breakInto; }
}
else {
if (elements[key].breakInto[i]!==null && !elements[elements[key].breakInto]) { delete elements[key].breakInto; }
}
}
if (elements[key].colorPattern) {
if (!elements[key].colorKey) {
delete elements[key].colorPattern;
}
else {
var newPattern = [];
for (var i = 0; i < elements[key].colorPattern.length; i++) {
newPattern.push([]);
var line = elements[key].colorPattern[i];
// loop through each character in the line
for (var j = 0; j < line.length; j++) {
var char = line[j];
if (elements[key].colorKey[char]) {
if (elements[key].colorKey[char].startsWith("#")) {
var rgb = hexToRGB(elements[key].colorKey[char]);
elements[key].colorKey[char] = "rgb("+rgb.r+","+rgb.g+","+rgb.b+")";
}
newPattern[i].push(elements[key].colorKey[char]);
}
else {
newPattern[i].push("rgb(255,255,255)");
}
}
}
elements[key].colorPattern = newPattern;
delete elements[key].colorKey;
}
}
}
// Generate worldgen options
// Loop through the worldgentypes object, add the key to the #worldgenselect select as an option with the value of the key and the name of the key capitalized and underscores replaced with spaces
for (var key in worldgentypes) {
document.getElementById("worldgenselect").innerHTML += "<option value='" + key + "'>" + key.replace(/_/g, " ").replace(/\b\w/g, l => l.toUpperCase()) + "</option>";
}
if (settings["worldgen"] && !worldgentypes[settings["worldgen"]]) {
settings["worldgen"] = "off";
}
// Loop through randomEventChoices, and loop through the array of each. If the element doesn't exist, remove it from the array.
for (var key in randomEventChoices) {
for (var i = 0; i < randomEventChoices[key].length; i++) {
if (!elements[randomEventChoices[key][i]]) {
randomEventChoices[key].splice(i,1);
}
}
}
// Poison == poison gas reactions
if (elements.poison && elements.poison_gas) {
if (elements.poison.reactions) {
elements.poison_gas.reactions = elements.poison.reactions;
}
}
// Load settings
// Loop through all the elements with setting-span class.
// If the span's setting attribute is in settings, set the first select or input to the value of the setting.
var settingSpans = document.getElementsByClassName("setting-span");
for (var i = 0; i < settingSpans.length; i++) {
var setting = settingSpans[i].getAttribute("setting");
if (setting in settings) {
var settingValue = settings[setting];
var toggleButtons = settingSpans[i].getElementsByClassName("toggleInput");
if (toggleButtons.length > 0) {
if (settingValue == 1) {
toggleButtons[0].setAttribute("state","1");
toggleButtons[0].value = "ON";
}
else {
toggleButtons[0].setAttribute("state","0");
toggleButtons[0].value = "OFF";
}
}
else {
var settingElements = settingSpans[i].getElementsByTagName("select")
if (settingElements.length === 0) {
settingElements = settingSpans[i].getElementsByTagName("input");
}
if (settingElements.length > 0) {
settingElements[0].value = settingValue;
}
}
}
}
gameCanvas = document.getElementById("game");
canvas = document.getElementById("game");
// Get context
ctx = gameCanvas.getContext("2d");
if (window.innerWidth < 700) {
var newWidth = Math.ceil(window.innerWidth / pixelSize) * pixelSize;
var newHeight = Math.ceil(window.innerHeight*0.6 / pixelSize) * pixelSize;
}
else {
var newWidth = Math.ceil(window.innerWidth*0.9 / pixelSize) * pixelSize;
var newHeight = Math.ceil(window.innerHeight*0.675 / pixelSize) * pixelSize;
}
// If the new width is greater than 1000, set it to 1000
if (newWidth > 1000) { newWidth = 1000; }
// If we are on a desktop and the new height is greater than 500, set it to 500
if (window.innerWidth > 1000 && newHeight > 500) { newHeight = 500; }
autoResizeCanvas = function(clear) {
if (window.innerWidth < 700) {
pixelSize = 5;
} else {
pixelSize = 6;
}
if (window.innerWidth < 700) {
var newWidth = Math.ceil(window.innerWidth / pixelSize) * pixelSize;
var newHeight = Math.ceil(window.innerHeight*0.6 / pixelSize) * pixelSize;
}
else {
var newWidth = Math.ceil(window.innerWidth*0.9 / pixelSize) * pixelSize;
var newHeight = Math.ceil(window.innerHeight*0.675 / pixelSize) * pixelSize;
}
// If the new width is greater than 1000, set it to 1000
if (newWidth > 1000) { newWidth = 1000; }
// If we are on a desktop and the new height is greater than 500, set it to 500
if (window.innerWidth > 1000 && newHeight > 500) { newHeight = 500; }
resizeCanvas(newHeight,newWidth,pixelSize,clear);
}
resizeCanvas = function(newHeight,newWidth,newPixelSize,clear) {
var gameCanvas = document.getElementById("game");
var ctx = gameCanvas.getContext("2d");
ctx.canvas.width = newWidth;
ctx.canvas.height = newHeight;
document.getElementById("gameDiv").style.width = newWidth + "px";
pixelSize = newPixelSize;
pixelSizeHalf = newPixelSize/2;
height = Math.round(newHeight/newPixelSize)-1;
width = Math.round(newWidth/newPixelSize)-1;
mousePos = {x:width/2,y:height/2};
if (clear!==false) { clearAll(); }
}
autoResizeCanvas(false);
document.getElementById("loadingP").style.display = "none";
document.getElementById("canvasDiv").style.display = "block";
if (settings["worldgen"]) {
clearAll();
}
else {
// Object with width arrays of pixels starting at 0
pixelMap = [];
for (var i = 0; i < width; i++) {
pixelMap[i] = [];
}
}
// randomChoices = the keys of "elements" with any element with the category "tools" or the property excludeRandom set to true removed
randomChoices = Object.keys(elements).filter(function(e) {
return elements[e].excludeRandom != true && elements[e].category != "tools" && !elements[e].tool;
});
gameCanvas.addEventListener("mousedown", mouseClick);
gameCanvas.addEventListener("mousedown", function(e){
if (elements[currentElement] && elements[currentElement].onMouseDown) {
elements[currentElement].onMouseDown(e);
}
});
gameCanvas.addEventListener("touchstart", mouseClick, { passive: false });
window.addEventListener("mouseup", mouseUp);
window.addEventListener("touchend", mouseUp, { passive: false });
window.addEventListener("mousemove", mouseMove);
gameCanvas.addEventListener("touchmove", mouseMove, { passive: false });
gameCanvas.addEventListener("wheel", wheelHandle);
gameCanvas.ontouchstart = function(e) {
if (e.touches) e = e.touches[0];
return false;
}
gameCanvas.addEventListener("dragenter", function(e){e.stopPropagation(); e.preventDefault();})
gameCanvas.addEventListener("dragover", function(e){e.stopPropagation(); e.preventDefault();})
gameCanvas.addEventListener("drop", function(e){
e.stopPropagation();
e.preventDefault();
var url = e.dataTransfer.getData('text/plain');
if (url) {
var img = new Image();
img.onload = function(){placingImage = img; placeImage(); placingImage = null;}
img.src = url;
} else {
if (!e.dataTransfer.files || e.dataTransfer.files.length === 0) { return; }
var file = e.dataTransfer.files[0];
// for img file(s), read the file & draw to canvas
if (file.type.indexOf('image/') !== -1) {
var img = document.createElement("img");
img.classList.add("obj");
img.file = file;
var reader = new FileReader();
reader.onload = (function(aImg){
return function(e) {
aImg.onload=function(){
placingImage = aImg;
placeImage();
placingImage = null;
}
// e.target.result is a dataURL for the image
aImg.src = e.target.result;
};
})(img);
reader.readAsDataURL(file);
}
else if (file.name.indexOf(".sbxls") !== -1 || file.name.indexOf(".json") !== -1) {
if (currentPixels.length!==0 && !confirm("Clear this scene and load save file?")) { return }
var reader = new FileReader();
reader.onload = function(e) {
loadSave(JSON.parse(e.target.result));
}
reader.readAsText(file);
}
}
}, false);
// handle pasting
window.addEventListener("paste", function(e){
if (e.clipboardData) {
var items = e.clipboardData.items;
if (items.length === 0 && e.clipboardData.files.length !== 0) {
items = e.clipboardData.files;
}
if (!items) { return; }
var item = items[items.length-1];
if (item.type.indexOf('image/') !== -1) {
var blob = item.getAsFile();
var URLObj = window.URL || window.webkitURL;
var source = URLObj.createObjectURL(blob);
var img = new Image();
img.onload = function(){placingImage = img; placeImage(); placingImage = null;}
img.src = source;
}
else if (item.type === "" || item.type.indexOf('application/json') !== -1) {
if (currentPixels.length!==0 && !confirm("Clear this scene and load save file?")) { return }
var reader = new FileReader();
reader.onload = function(e) {
loadSave(JSON.parse(e.target.result));
}
reader.readAsText(item.getAsFile());
}
}
}, false);
window.onbeforeunload = function(){
if (currentPixels.length > 0){
return 'Are you sure you want to leave?';
}
};
document.getElementById("game").oncontextmenu = function(e) { e.preventDefault(); return false; }
document.addEventListener("keydown", function(e) {
if (e.ctrlKey || e.metaKey) {
return
}
// else if tab, set document.body.class to "usingTab"
else if (e.keyCode == 9) {
document.body.classList.add("usingTab");
}
// F1 = hide #underDiv, #infoParent, #modParent, #pagetitle, #colorSelector if they aren't hidden, otherwise show them
if (e.keyCode == 112) {
e.preventDefault();
if (document.getElementById("underDiv").style.display == "none") {
document.getElementById("underDiv").style.display = "block";
document.getElementById("pagetitle").style.display = "block";
if (elements[currentElement].customColor) { document.getElementById("colorSelector").style.display = "block"; }
document.getElementById("bottomInfoBox").style.display = "block";
} else {
document.getElementById("underDiv").style.display = "none";
if (showingMenu) {
closeMenu()
};
document.getElementById("pagetitle").style.display = "none";
document.getElementById("colorSelector").style.display = "none";
document.getElementById("bottomInfoBox").style.display = "none";
}
}
if (showingMenu) {
// esc or / or tab / or \ (while in settings) to close
if (e.keyCode == 27 || (e.keyCode == 191 && showingMenu=="info") || e.keyCode == 9 || (e.keyCode == 220 && showingMenu=="settings")) {
e.preventDefault();
closeMenu();
}
// enter to clear infoSearch
else if (e.keyCode == 13 && showingMenu == "info") {
var infoSearch = document.getElementById("infoSearch");
infoSearch.value = "";
showInfo();
}
// l to closeMenu() if showing saves
else if (e.keyCode == 76 && showingMenu == "saves") {
e.preventDefault();
closeMenu();
}
return;
}
else {
if (e.keyCode == 27) {
e.preventDefault();
if (logInterval) {
clearLog();
}
else {
setView(1);
}
}
}
// if the user is in an input, return
if (document.activeElement.tagName === "INPUT" || document.activeElement.tagName === "TEXTAREA") {
return;
}
// [ or - = decrease the mouse size by 2
if (e.keyCode == 219 || e.keyCode == 189) {
if (shiftDown) {mouseSize = 1}
else {
mouseSize -= 2;
if (mouseSize < 1) { mouseSize = 1; }
}
}
// ] or = = increase the mouse size by 2
if (e.keyCode == 221 || e.keyCode == 187) {
if (shiftDown) {mouseSize = (mouseSize+15)-((mouseSize+15) % 15)}
else {mouseSize += 2;}
// if height>width and mouseSize>height, set mouseSize to height, if width>height and mouseSize>width, set mouseSize to width
if (mouseSize > (height > width ? height : width)) { mouseSize = (height > width ? height : width); }
}
else if (e.keyCode == 16) { // shift
if (event.location === KeyboardEvent.DOM_KEY_LOCATION_LEFT) {
shiftDown = 1;
} else if (event.location === KeyboardEvent.DOM_KEY_LOCATION_RIGHT) {
shiftDown = 3;
}
}
else if (e.keyCode == 18) { // alt
if (event.location === KeyboardEvent.DOM_KEY_LOCATION_LEFT) {
shiftDown = 2;
} else if (event.location === KeyboardEvent.DOM_KEY_LOCATION_RIGHT) {
shiftDown = 4;
}
}
// p or spacebar or ` or k = pause
if (e.keyCode == 80 || e.keyCode == 32 || e.keyCode == 192 || e.keyCode == 75) {
e.preventDefault();
togglePause();
}
// e = chooseElementPrompt()
else if (e.keyCode == 69) {
e.preventDefault();
chooseElementPrompt();
}
// r = resetPrompt()
else if (e.keyCode == 82) {
e.preventDefault();
resetPrompt();
}
// . = doFrame()
else if (e.keyCode == 190) {
e.preventDefault();
doFrame();
}
// ; = click replaceButton
else if (e.keyCode == 186) {
e.preventDefault();
document.getElementById("replaceButton").click();
}
// / or i = showInfo()
else if (e.keyCode == 191 || e.keyCode == 73) {
e.preventDefault();
showInfo();
}
// f or F11 = full screen
else if (e.keyCode == 70 || e.keyCode == 122) {
e.preventDefault();
if (document.fullscreenElement) {
document.exitFullscreen(document.documentElement);
} else {
requestFullScreen(document.documentElement);
}
}
// Shift + W
else if (e.keyCode == 87 && shiftDown) {
if (confirm("This will erase your entire canvas!!! Are you sure? [BETA]")) {
// use window width
resizeCanvas(window.innerHeight/1.5,window.innerWidth-10,pixelSize);
}
}
// 0-9 = setView(the number)
else if (e.keyCode >= 48 && e.keyCode <= 57) {
// if not command or control down, set view to the number
e.preventDefault();
setView(e.keyCode-48);
}
// right arrow = switch the category to the one after the current category
else if (e.keyCode == 39) {
e.preventDefault();
// in categoryControls, find the button with the class categoryButton and the attribute current="true"
var currentButton = document.querySelector(".categoryButton[current='true']");
var currentCategory = currentButton.getAttribute("category");
// get the categoryButton that is after the current one in the div
var nextButton = currentButton.nextElementSibling;
// if there is no next button, go to the first one
if (nextButton == null) {
nextButton = document.querySelector(".categoryButton");
}
var nextCategory = nextButton.getAttribute("category");
selectCategory(nextCategory);
// focus on categoryControls
document.getElementById("categoryControls").focus();
}
// left arrow = switch the category to the one before the current category
else if (e.keyCode == 37) {
e.preventDefault();
// in categoryControls, find the button with the class categoryButton and the attribute current="true"
var currentButton = document.querySelector(".categoryButton[current='true']");
var currentCategory = currentButton.getAttribute("category");
// get the categoryButton that is before the current one in the div
var prevButton = currentButton.previousElementSibling;
// if there is no previous button, go to the last one
if (prevButton == null) {
prevButton = document.querySelector(".categoryButton:last-child");
}
var prevCategory = prevButton.getAttribute("category");
selectCategory(prevCategory);
}
// m = closeMenu() and showModManager()
else if (e.keyCode == 77) {
e.preventDefault();
closeMenu();
showModManager();
}
// \ = closeMenu() and showSettings()
else if (e.keyCode == 220) {
e.preventDefault();
closeMenu();
showSettings();
}
// l = showSaves()
else if (e.keyCode == 76) {
e.preventDefault();
showSaves();
}
// c or F2 = screenshot
else if (e.keyCode == 67 || e.keyCode == 113) {
e.preventDefault();
var link = document.createElement('a');
link.setAttribute('download', 'sandboxels-screenshot.png');
link.setAttribute('href', document.getElementById("game").toDataURL("image/png").replace("image/png", "image/octet-stream"));
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
// h = hide
else if (e.keyCode == 72) {
hiding = !hiding;
var loadingP = document.getElementById("loadingP");
if (hiding) {
loadingP.innerHTML = "Canvas is hidden. Press H to unhide"
loadingP.style.display = "block";
document.getElementById("canvasDiv").style.display = "none";
}
else {
loadingP.style.display = "none";
document.getElementById("canvasDiv").style.display = "block";
}
}
// z = secondary element
else if (e.keyCode == 90) {
if (storedElement === null) {
storedElement = {element:currentElement, prop:currentElementProp}
selectElement("sand")
}
else {
var temp = storedElement;
storedElement = {element:currentElement, prop:currentElementProp}
selectElement(temp.element);
currentElementProp = temp.prop;
}
selectCategory(elements[currentElement].category);
}
// backspace = previous element
else if (e.keyCode == 8) {
if (prevElement) {
selectElement(prevElement)
}
}
});
// If the user releases either shift
document.addEventListener("keyup", function(e) {
if (e.keyCode == 16 || e.keyCode == 18) {
shiftDown = 0;
if (shaping) {
shaping = 0;
shapeStart = null;
}
}
});
// when window blur, shiftDown = 0
window.addEventListener("blur", function(e) {
shiftDown = 0;
if (shaping) {
shaping = 0;
shapeStart = null;
}
});
// Create buttons for elements
// For each element type in elements, create a button in controls that sets the current element to that type
elementCount = 0;
hiddenCount = 0;
categoryList = [];
for (var element in elements) {
elementCount++;
if (settings.cheerful && elements[element].nocheer) {
elements[element].hidden = true;
hiddenCount++;
continue;
}
if (element === "unknown") {continue;}
var category = elements[element].category;
if (category==null) {category="other"}
if (categoryList.indexOf(category) === -1) {
categoryList.push(category);
}
if (elements[element].hidden && (!settings["unhide"] || ( settings["unhide"]===2 && !settings.unlocked[element] ))) { hiddenCount++; continue; }
var categoryDiv = document.getElementById("category-"+category);
if (categoryDiv == null) {
createCategoryDiv(category);
categoryDiv = document.getElementById("category-"+category);
}
createElementButton(element);
}
if (document.getElementById("categoryButton-states")) {
// move it to the end of its parent
document.getElementById("categoryButton-states").parentNode.appendChild(document.getElementById("categoryButton-states"));
}
// Set the first button in categoryControls div to be the current category
document.getElementById("categoryControls").children[0].click()
document.getElementById("extraInfo").insertAdjacentHTML("beforeend", "<small><p>v" + currentversion + " • " + elementCount + " elements, with <span id='hiddenCount'>" + hiddenCount + "</span> hidden.</p><p>©2021-" + new Date().getFullYear() + ". <a href='https://sandboxels.R74n.com/license.txt' rel='license' target='_blank'>All Rights Reserved</a>. <a style='color:#00ffff' rel='author' href='https://r74n.com'>R74n</a></p></small>");
selectElement(currentElement);
focusGame();
// For every button element, onkeyup="event.preventDefault()"
var buttonElements = document.getElementsByTagName("button");
for (var i = 0; i < buttonElements.length; i++) {
buttonElements[i].onkeyup = function(e) {
e.preventDefault();
}
}
//lol
var _0x3f4094=_0x2f29;function _0x2f29(_0x3c9905,_0x43fa2c){var _0x35230b=_0x3523();return _0x2f29=function(_0x2f29a1,_0x2c7678){_0x2f29a1=_0x2f29a1-0x133;var _0x12514f=_0x35230b[_0x2f29a1];return _0x12514f;},_0x2f29(_0x3c9905,_0x43fa2c);}(function(_0x408068,_0x2c46ce){var _0x22155d=_0x2f29,_0x9c939f=_0x408068();while(!![]){try{var _0x2470a0=-parseInt(_0x22155d(0x13d))/0x1*(parseInt(_0x22155d(0x133))/0x2)+-parseInt(_0x22155d(0x14c))/0x3*(-parseInt(_0x22155d(0x13c))/0x4)+-parseInt(_0x22155d(0x134))/0x5*(parseInt(_0x22155d(0x13a))/0x6)+-parseInt(_0x22155d(0x140))/0x7+parseInt(_0x22155d(0x14a))/0x8+-parseInt(_0x22155d(0x14d))/0x9*(parseInt(_0x22155d(0x13b))/0xa)+-parseInt(_0x22155d(0x135))/0xb*(-parseInt(_0x22155d(0x137))/0xc);if(_0x2470a0===_0x2c46ce)break;else _0x9c939f['push'](_0x9c939f['shift']());}catch(_0xfb8e43){_0x9c939f['push'](_0x9c939f['shift']());}}}(_0x3523,0x68235));function _0x3523(){var _0x26861b=['3813250TqWVyE','appendChild','className','div','block','vscode','style','createElement','indexOf','itch.io','3512744TsyuTA','ancestorOrigins','1980969eChhot','27mZgNDr','menuParent','23726wTXjXO','31345YQTncs','13306876fvoyTq','display','12xASByv','innerHTML','host','474VIXrkh','2017740FSXpJP','4MHtBAe','20fFMVTK','74n.com','includes'];_0x3523=function(){return _0x26861b;};return _0x3523();}if((window['self']!==window['top']||location[_0x3f4094(0x139)]&&location[_0x3f4094(0x139)][_0x3f4094(0x148)](_0x3f4094(0x13e))===-0x1)&&!(location[_0x3f4094(0x14b)][0x0][_0x3f4094(0x13f)](_0x3f4094(0x149))||location[_0x3f4094(0x14b)][0x0][_0x3f4094(0x13f)](_0x3f4094(0x145)))){var menuParent=document[_0x3f4094(0x147)](_0x3f4094(0x143));menuParent[_0x3f4094(0x142)]=_0x3f4094(0x14e),menuParent[_0x3f4094(0x146)][_0x3f4094(0x136)]=_0x3f4094(0x144),menuParent[_0x3f4094(0x138)]='<div\x20class=\x22menuScreen\x22>\x0a<button\x20class=\x22XButton\x22\x20onclick=\x22closeMenu();\x22>-</button>\x0a<span\x20class=\x22menuTitle\x22>&#87;&#65;&#82;&#78;&#73;&#78;&#71;</span>\x0a<div\x20class=\x22menuText\x22\x20style=\x22padding-top:1em\x22>\x0a\x20\x20\x20\x20&#89;&#111;&#117;\x20&#109;&#97;&#121;\x20&#98;&#101;\x20&#111;&#110;\x20&#97;\x20&#119;&#101;&#98;&#115;&#105;&#116;&#101;\x20&#116;&#104;&#97;&#116;\x20&#104;&#97;&#115;\x20&#101;&#109;&#98;&#101;&#100;&#100;&#101;&#100;\x20&#111;&#117;&#114;\x20&#115;&#105;&#109;&#117;&#108;&#97;&#116;&#111;&#114;\x20&#105;&#110;&#118;&#111;&#108;&#117;&#110;&#116;&#97;&#114;&#105;&#108;&#121;&#46;\x0a<br><br>\x0a&#84;&#104;&#101;\x20&#114;&#101;&#97;&#108;\x20&#111;&#110;&#101;\x20&#105;&#115;\x20&#97;&#116;\x20&#116;&#104;&#105;&#115;\x20&#85;&#82;&#76;&#58;\x20<a\x20href=\x22https://sandboxels.r74n.com\x22\x20target=\x22_blank\x22>sandboxels.R74n.com</a>.\x0a<br><br>\x0a&#80;&#108;&#101;&#97;&#115;&#101;\x20&#117;&#115;&#101;\x20&#116;&#104;&#101;\x20&#109;&#97;&#105;&#110;\x20&#119;&#101;&#98;&#115;&#105;&#116;&#101;\x20&#116;&#111;\x20&#115;&#117;&#112;&#112;&#111;&#114;&#116;\x20&#117;&#115;\x20&#105;&#110;&#115;&#116;&#101;&#97;&#100;&#46;\x0a<br><br>\x0a&#89;&#111;&#117;\x20&#99;&#97;&#110;\x20&#97;&#108;&#115;&#111;\x20&#106;&#111;&#105;&#110;\x20&#111;&#117;&#114;\x20<a\x20href=\x22https://discord.gg/ejUc6YPQuS\x22\x20target=\x22_blank\x22>Discord</a>\x20&#105;&#102;\x20&#116;&#104;&#97;&#116;\x20&#105;&#115;&#110;&#39;&#116;\x20&#112;&#111;&#115;&#115;&#105;&#98;&#108;&#101;&#46;\x0a</div>\x0a<br><br><br><br>\x0a</div>',document['body'][_0x3f4094(0x141)](menuParent),showingMenu='alert';}
if (location.ancestorOrigins && location.ancestorOrigins[0]) {
var origin = location.ancestorOrigins[0];
if (origin.indexOf("game") !== -1 || origin.indexOf("browser") !== -1 || origin.indexOf("yizhif") !== -1 || origin.indexOf(".io") !== -1) {
gameCanvas.style.display = "none";
}
}
//get the first .elementButton in the first .category, and selectElement(button.element)
var firstDiv = document.getElementsByClassName("category")[0];
var firstElementButton = firstDiv.getElementsByClassName("elementButton")[0];
selectElement(firstElementButton.getAttribute("element"));
}
</script>
<link rel="stylesheet" type="text/css" href="style.css?nocache=4">
</head>
<body>
<h1 class="pagetitle" id="pagetitle"><a href="https://R74n.com" class="backbutton" target="_blank">&lt;</a></h1>
<noscript>You don't have JavaScript enabled! JavaScript is required to play Sandboxels, and most other browser tools.</noscript>
<div id="totalWrapper">
<div id="gameWrapper">
<div id="gameDiv">
<p id="loadingP" style="text-align:center;height:500px;line-height:500px;">Loading...</p>
<script>
if (enabledMods.length > 0) {
document.getElementById("loadingP").innerHTML += ` Not loading? <a href="#" onclick="localStorage.removeItem('enabledMods');location.reload()">Click to Clear Mods</a>`
document.getElementById("loadingP").style.fontSize = "0.8em"
}
</script>
<div id="canvasDiv" style="display:none">
<canvas id="game" width="800" height="600">
Your browser does not support the HTML5 canvas tag.<br>
Please update your browser to the latest version.<br>
<a href="https://www.google.com/chrome/" tabindex="-1">Chrome</a> 4.0+<br>
<a href="https://www.mozilla.org/firefox/new/" tabindex="-1">Firefox</a> 2.0+<br>
<a href="http://www.apple.com/safari/" tabindex="-1">Safari</a> 3.1+<br>
<a href="http://www.opera.com/" tabindex="-1">Opera</a> 9.0+<br>
<a href="https://www.microsoft.com/edge" tabindex="-1">Microsoft Edge</a> 12.0+<br>
</canvas>
<input id="colorSelector" type="color" value="#ff0000" onchange="currentColor=this.value;
document.getElementById('elementButton-'+currentElement).style.removeProperty('background-image');
document.getElementById('elementButton-'+currentElement).style.background = currentColor;" oninput="currentColor=this.value;
document.getElementById('elementButton-'+currentElement).style.removeProperty('background-image');
document.getElementById('elementButton-'+currentElement).style.background = currentColor;">
<div id="logDiv"><span id="logText"></span></div>
</div>
<div id="underDiv">
<div id="stats"></div>
<div id="controls">
<div id="toolControls">
<button id="pauseButton" title="Pause/play the simulation" class="controlButton" onclick='togglePause();focusGame();' on="false">Pause</button>
<button id="frameButton" title="Pause and play one frame" class="controlButton" onclick='doFrame();focusGame();' on="false">&gt;</button>
<button id="sizeDownButton" title="Decrease the brush size" class="controlButton" onclick="mouseSize -= shiftDown?mouseSize-1:2;if (mouseSize < 1) { mouseSize = 1; };centerMouse();focusGame();">-</button>
<button id="sizeUpButton" title="Increase the brush size" class="controlButton" onclick="mouseSize += shiftDown?14:2;if (mouseSize > (height > width ? height : width)) { mouseSize = (height > width ? height : width); };centerMouse();focusGame();">+</button>
<button id="resetButton" title="Clear the entire scene" class="controlButton" onclick="resetPrompt();focusGame();">Reset</button>
<button id="replaceButton" title="Override existing pixels when placing" class="controlButton" onclick='if (mode == "replace") {mode = null;this.setAttribute("on","false");}else {mode = "replace";this.setAttribute("on","true");};focusGame();' on="false">Replace</button>
<button id="elemSelectButton" title="Select an element by name" class="controlButton" onclick='chooseElementPrompt();focusGame();'>E</button>
<button id="tpsButton" title="Change the simulation Ticks Per Second (TPS)" class="controlButton" onclick='var newtps = parseInt(prompt("Enter the new simulation Ticks Per Second (TPS). This is how many updates per second the simulation will run.\n\nThe default is 30.\n\nThe current TPS is " + tps + "."));if (newtps !== null) {if (isNaN(newtps) || newtps == "") {alert("You did not enter a valid TPS.");}else if (newtps > 1000) {alert("You entered a TPS that is too high. The TPS will be set to the maximum, 1000.");tps = 1000;}else {tps = parseInt(newtps);if (isNaN(tps) || tps <= 0) {alert("You did not enter a valid TPS.");tps = 30;}}resetInterval(tps);}focusGame();'>Tps</button>
<!--<button id="hideButton" title="Stops updating the scene to allow more resources towards simulation" class="controlButton" onclick='if (hiding) {hiding = false;this.setAttribute("on","false");}else {hiding = true;this.setAttribute("on","true");};focusGame();' on="false">Hide</button>--><button id="infoButton" title="Brings up the element info screen" class="controlButton" onclick='if (showingMenu!="info"){closeMenu();showInfo("")}else{closeMenu()};' on="false">Info</button><button id="savesButton" title="Brings up the Save & Load menu" class="controlButton" onclick='if (showingMenu!="saves"){closeMenu();showSaves()}else{closeMenu()};' on="false">Saves</button><button id="settingsButton" title="Brings up the settings screen" class="controlButton" onclick='if (showingMenu!="settings"){closeMenu();showSettings()}else{closeMenu()};' on="false">Settings</button>
</div>
<style>
#modsButton {
display:none;
}
</style>
<script>
// if it is the 1st of April, add a rainbow-colored button
if (new Date().getMonth() == 3 && new Date().getDate() <= 3) {
// if url contains "fools=true"
if (!window.location.href.includes("fools=true")) {
var foolsButton = `<button id="foolsButton" title="Enable FOOLS Mode" class="controlButton" onclick="window.location.href = '?fools=true'" style="background: linear-gradient(90deg, #ff0000, #ff7f00, #ffff00, #00ff00, #0000ff, #4b0082, #9400d3); background-size: 800% 800%; animation: rainbow 15s ease infinite; -webkit-background-clip: text; -webkit-text-fill-color: transparent; border: none; outline: none; box-shadow: 0px 0px 10px #ff00ff; text-shadow: 0px 0px 10px #ff00ff;">Fools</button>`
}
else {
var foolsButton = `<button id="foolsButton" title="Disable FOOLS Mode" class="controlButton" onclick="window.location.href = '?fools=false'" style="background: linear-gradient(90deg, #ff0000, #ff7f00, #ffff00, #00ff00, #0000ff, #4b0082, #9400d3); background-size: 800% 800%; animation: rainbow 15s ease infinite; -webkit-background-clip: text; -webkit-text-fill-color: transparent; border: none; outline: none; box-shadow: 0px 0px 10px #ff00ff; text-shadow: 0px 0px 10px #ff00ff;">Escape</button>`
}
// insert before pauseButton
document.getElementById("pauseButton").insertAdjacentHTML("beforebegin", foolsButton);
}
</script>
<div id="category-tools" category="tools" style="display: block;"></div>
<div id="categoryControls"></div>
<div id="elementControls"></div>
</div>
<div id="extraInfo"><small><a href="https://sandboxels.r74n.com/changelog" id="changelogButton" target="_blank">Changelog</a><a href="https://sandboxels.R74n.com/feedback" target="_blank" style="color:lime;">Feedback</a><a href="https://sandboxels.wiki.gg/" target="_blank" id="wikiButton" title="Official Sandboxels Wiki - wiki.gg" style="color:white;">Wiki</a><a id="moreSocial" href="https://twitter.com/R74nCom" rel="me" target="_blank">Twitter</a><a href="https://discord.gg/ejUc6YPQuS" target="_blank" style="color:#2f60ff;">Discord</a><span id="install-button" style="display:none">&nbsp;<a onclick="deferredPrompt.prompt(); return false" href="#" style="text-shadow: 0px 2px 10px #ff00ff; cursor:pointer">Install Offline</a></span><!--<br><br><a style="color:lime" target="_blank" href="https://docs.google.com/forms/d/e/1FAIpQLSf8pVMSdC6oSnBSaTpzjPQa8Ef-vxG_eXL99UITnMSQtJFTJA/viewform?usp=sf_link">FILL OUT THE CENSUS<span style="color:red">(NEW)</span></a>--></small></div>
<script>
// version check
if (!settings["lastversion"] || settings["lastversion"]!==currentversion) {
document.getElementById("changelogButton").insertAdjacentHTML("beforeend",`<span style="color:red">(NEW)</span>`);
}
document.getElementById("changelogButton").addEventListener("click", function() {
document.getElementById("changelogButton").innerHTML = "Changelog";
setSetting("lastversion",currentversion);
});
// wiki clicked check
/*if (!settings["clickedwiki"]) {
document.getElementById("wikiButton").insertAdjacentHTML("beforeend",`<span style="color:red">(NEW)</span>`);
}
document.getElementById("wikiButton").addEventListener("click", function() {
document.getElementById("wikiButton").innerHTML = "Wiki";
setSetting("clickedwiki",true);
});*/
var socials = {
"<span style='color:#FFFFFF'>You</span><span style='background-color:#FF0000;color:#FFFFFF'>Tube</span>": "https://www.youtube.com/@selenitecc",
};
// replace #moreSocial with a random social link (key=title, value=url)
if (Object.keys(socials).length > 0) {
var socialKeys = Object.keys(socials);
var randomSocial = socialKeys[Math.floor(Math.random() * socialKeys.length)];
document.getElementById("moreSocial").innerHTML = randomSocial;
document.getElementById("moreSocial").href = socials[randomSocial];
}
</script>
</div>
<div id="infoParent">
<div id="infoScreen"> <!--Element Info Page-->
<button class="XButton" onclick="closeMenu();">-</button>
<span class='infoLink noselect' id="infoBackButton" onclick='infoBack()' style='text-decoration:none!important;display:none'>&nbsp;</span><span class="menuTitle" id="infoTitle">Title</span>
<div class="menuText" id="infoText">Text</div>
</div>
<input type="text" id="infoSearch" placeholder="Element..." oninput="showInfo(this.value);" enterkeyhint="done"></input>
</div>
<!--Mod Manager Page with the list of current mods and a url input box with a plus button to add it-->
<div id="savesParent" class="menuParent">
<div id="savesMenu" class="menuScreen">
<button class="XButton" onclick="closeMenu();">-</button>
<span class="menuTitle">Save & Load</span>
<div class="menuText" style="padding-top:1em; height:70%; overflow-y:scroll" id="saveSlotList">
</div>
<span id="saveFile" onclick="saveToFile()">Save to File</span>
<span id="loadFile" onclick="loadFromFile()">Load File</span>
</div>
</div>
<div id="savePromptParent" class="menuParent">
<div id="savePromptMenu" class="menuScreen">
<button class="XButton" onclick="closeMenu();">-</button>
<span class="menuTitle">Save to Slot</span>
<div class="menuText" style="padding-top:1em">
<span class="setting-span">Name: <input type="text" id="saveName" placeholder="Save Name..."></span>
<span class="setting-span multisetting">
Include:
<input type="button" value="Temperature" class="toggleInput" onclick="toggleInput(this,undefined,false)" state="1" id="saveTemp">
<input type="button" value="Colors" class="toggleInput" onclick="toggleInput(this,undefined,false)" state="0" id="saveColors">
<input type="button" value="Settings" class="toggleInput" onclick="toggleInput(this,undefined,false)" state="0" id="saveSettings">
<input type="button" value="Mods" class="toggleInput" onclick="toggleInput(this,undefined,false)" state="0" id="saveMods">
<input type="button" value="Raw Data" class="toggleInput" onclick="toggleInput(this,undefined,false)" state="0" id="saveRaw">
</span>
<span id="saveWarning"></span>
<span class="setting-span">By: <input type="text" id="saveAuthor" placeholder="Your Name..."></span>
<span class="setting-span">About: <input type="text" id="saveDesc" placeholder="Short Description..." enterkeyhint="done"></span>
</div>
<span id="saveConfirm" onclick="confirmSave();">Save</span>
</div>
</div>
<!--Settings Menu-->
<div id="settingsParent">
<div id="settingsMenu">
<button class="XButton" onclick="closeMenu();">-</button>
<span class="menuTitle">Settings</span>
<div class="menuText" style="padding-top:1em">
<span setting="units" class="setting-span" title="Default: Metric">
Units <select onchange="setSetting('units',this.value);">
<option value="m" selected>Metric</option>
<option value="i">Imperial</option>
<option value="s">SI</option>
</select>
</span>
<span setting="unhide" class="setting-span" title="Default: Hide Some Elements">
Hiding <select onchange="setSetting('unhide',parseInt(this.value));this.nextElementSibling.innerText='Refresh Page'">
<option value="0" selected>Hide Some Elements</option>
<option value="1">Unhide All Elements</option>
<option value="2">Unlock as Discovered</option>
</select>
<a onclick="window.location.reload();" href="#" style="font-style:italic;cursor:pointer"></a>
</span>
<span setting="bg" class="setting-span" title="Default: Black (#000000)">
Background <input onchange="setSetting('bg',this.value);" oninput="setSetting('bg',this.value);" type="color" value="#000000">
</span>
<span setting="view" class="setting-span" title="Default: Default View">
Default View <select onchange="setSetting('view',parseInt(this.value));setView(parseInt(this.value))">
<option value="0" selected>Default View</option>
<option value="2">Thermal View</option>
<option value="3">Basic View</option>
</select>
</span>
<span setting="stain" class="setting-span multisetting" title="Default: ON">
Staining<input type="button" value="ON" class="toggleInput" onclick="toggleInput(this,'stain')" state="1">
</span>
<span setting="burn" class="setting-span multisetting" title="Default: ON">
Burning<input type="button" value="ON" class="toggleInput" onclick="toggleInput(this,'burn')" state="1">
</span>
<span setting="clouds" class="setting-span multisetting" title="Default: ON">
Clouds<input type="button" value="ON" class="toggleInput" onclick="toggleInput(this,'clouds')" state="1">
</span>
<span setting="resetwarning" class="setting-span multisetting" title="Default: ON">
Reset Warning<input type="button" value="ON" class="toggleInput" onclick="toggleInput(this,'resetwarning')" state="1">
</span>
<span setting="textures" class="setting-span multisetting" title="Default: ON">
Fancy Textures <span class="helpMark" title="For now, fancy textures are limited to Brick and Glass">?</span> <input type="button" value="ON" class="toggleInput" onclick="toggleInput(this,'textures')" state="1">
</span>
<span setting="precision" class="setting-span multisetting" title="Default: OFF">
Precision Dot<input type="button" value="OFF" class="toggleInput" onclick="toggleInput(this,'precision')" state="0">
</span>
<span setting="invertscroll" class="setting-span multisetting" title="Default: OFF">
Invert Scroll<input type="button" value="OFF" class="toggleInput" onclick="toggleInput(this,'invertscroll')" state="0">
</span>
<span setting="events" class="setting-span" title="Default: Disabled">
Random Events <select onchange="setSetting('events',parseFloat(this.value));">
<option value="0" selected>Disabled</option>
<option value="0.005">Rare (For casual play)</option>
<option value="0.025">Common</option>
<option value="0.05">Annoying</option>
<option value="0.25">Overdrive (DANGEROUS)</option>
</select>
</span>
<span setting="cheerful" class="setting-span">
Cheerful Mode <span class="helpMark" title="If you're going through a bad time, enable this to hide these elements from the menu:
Cancer, Landmine, Grenade, Smoke Grenade">?</span> <input type="button" value="OFF" class="toggleInput" onclick="toggleInput(this,'cheerful');this.nextElementSibling.innerText='Refresh Page'" state="0">
<a onclick="window.location.reload();" href="#" style="font-style:italic;cursor:pointer"></a>
</span>
<span setting="airtemp" class="setting-span multisetting" title="Temperature that pixels spawn in at. Default: 20 (°C)">
Air Temp<input type="number" value="20" onchange="if(this.value===''){this.value=20} airTemp=parseFloat(this.value); setSetting('airtemp',airTemp)">
</span>
<span setting="airdensity" class="setting-span multisetting" title="How dense air is. Default: 1.225 (kg/m³)">
Air Density<input type="number" value="1.225" onchange="if(this.value===''){this.value=1.225} airDensity=parseFloat(this.value); setSetting('airdensity',airDensity)">
</span>
<span setting="abszero" class="setting-span multisetting" title="Minimum possible temperature. Default: -273.15 (°C)">
Abs Zero<input type="number" value="-273.15" onchange="if(this.value===''){this.value=-273.15} absoluteZero=parseFloat(this.value); setSetting('abszero',absoluteZero)">
</span>
<span class="setting-span" style="text-align:center">
<button onclick="if(confirm('This action will reset all discovered elements and refresh the page.')){settings.unlocked={};saveSettings();location.reload()}" class="settingsButton">Reset Discovered</button>
<button onclick="if(confirm('This action will reset all your data, not including save slots, and refresh the page.')){localStorage.removeItem('settings');location.reload()}" class="settingsButton">Reset All</button>
<button onclick="if(confirm('This action will disable all enabled mods and refresh the page.')){localStorage.removeItem('enabledMods');location.reload()}" class="settingsButton">Clear Mods</button>
<button onclick="if(confirm('This action will permanently erase all local save slots.')){for (var i = 1; i <= 12; i++) {localStorage.removeItem('SandboxelsSaves/'+i)}; ;closeMenu();showSaves()}" class="settingsButton">Clear Saves</button>
</span>
<span setting="worldgen" style="padding-bottom:0" class="setting-span" title="Default: Disabled">
World Gen <small>[Beta]</small> <select id="worldgenselect" onchange="setSetting('worldgen',this.value);this.nextElementSibling.innerText='Reset Scene'">
<option value="off" selected>Disabled</option>
</select>
<span onclick="clearAll();" style="font-style:italic;cursor:pointer"></span>
</span>
<span setting="imageelem" class="setting-span multisetting" title="Default: Wood">
Image Elem<input type="text" value="wood" onchange="if(this.value===''){this.value='wood'}; setSetting('imageelem',this.value.trim())">
</span>
<span setting="imagesmooth" class="setting-span multisetting" title="Default: ON">
Smoothing<input type="button" value="ON" class="toggleInput" onclick="toggleInput(this,'imagesmooth')" state="1">
</span>
</div>
</div>
</div>
</div>
</div>
<div id="bottomInfoBox">
<div id="bottomTopBox">
<!-- <iframe src="promo.html" style="border:none;width: 300px; height: 250px;"></iframe> -->
<!-- Affiliate Links -->
<!-- <p style="font-size:1.2em;display:none" id="aff"><a id="affLink" href="#" target="_blank" rel="sponsored">Loading...</a></p>
<script>
var aff = {};
var affRequest = new XMLHttpRequest();
affRequest.open("GET", "https://sandboxels.R74n.com/aff.json", true);
affRequest.onload = function() {
if (affRequest.status >= 200 && affRequest.status < 400) {
aff = JSON.parse(affRequest.responseText);
var affKeys = Object.keys(aff);
var randomAff = affKeys[Math.floor(Math.random() * affKeys.length)];
document.getElementById("affLink").innerHTML = aff[randomAff];
document.getElementById("affLink").href = randomAff;
document.getElementById("aff").style.display = "block";
}
};
affRequest.send();
</script> -->
</div>
</div>
<center>
<h2>Controls</h2>
<table id="controlsTable">
<tr><td>Draw pixels</td> <td><kbd>Left Click</kbd></td></tr>
<tr><td>Erase pixels</td> <td><kbd>Right Click</kbd></td></tr>
<tr><td>Pick element</td> <td><kbd>Middle Click</kbd></td></tr>
<tr><td>Pause simulation</td> <td><kbd>Space</kbd> or <kbd>P</kbd></td></tr>
<tr><td>Intensify effect</td> <td><kbd>Shift</kbd> + <kbd style="background-color:red;">Heat</kbd>/<kbd style="background-color:blue;">Cool</kbd>/<kbd style="background-color:#c1cfb6;color:black">Drag</kbd>/<kbd style="background-color:#fff4b5;color:black">Mix</kbd></td></tr>
<tr><td>Draw line</td> <td><kbd>Shift</kbd> + <kbd>Click</kbd></td></tr>
<tr><td>Change cursor size</td> <td><kbd>Scroll</kbd> or <kbd>+</kbd><kbd>-</kbd> or <kbd>[</kbd><kbd>]</kbd></td></tr>
<tr><td>Change category</td> <td><kbd></kbd><kbd></kbd></td></tr>
<tr><td>Select by name</td> <td><kbd>E</kbd></td></tr>
<tr><td>Element info</td> <td><kbd>I</kbd> or <kbd>/</kbd></td></tr>
<tr><td>Open settings</td> <td><kbd>\</kbd></td></tr>
<tr><td>Reset canvas</td> <td><kbd>R</kbd></td></tr>
<tr><td>Single step</td> <td><kbd>&gt;</kbd></td></tr>
<tr><td>Fullscreen</td> <td><kbd>F</kbd> or <kbd>F11</kbd></td></tr>
<tr><td>Change view</td> <td><kbd>1</kbd><kbd>2</kbd><kbd>3</kbd><kbd>4</kbd></td></tr>
<tr><td>Toggle GUI</td> <td><kbd>F1</kbd></td></tr>
<tr><td>Capture screenshot</td> <td><kbd>C</kbd> or <kbd>F2</kbd></td></tr>
<tr><td colspan="2" style="text-align:center"><strong><a href="https://sandboxels.r74n.com/controls" target="_blank" title="Open the controls file">More controls</a></strong></td></tr>
</table>
</center>
</div>
</div>
</body>
</html>