2021-12-23 00:21:51 -05:00
< html >
< head >
< meta charset = "utf-8" >
< title > Sandboxels< / title >
< meta charset = "utf-8" >
< meta name = "description" content = "A falling sand simulation game." >
< meta name = "keywords" content = "falling sand, elements, pixel art, simulator, powder" >
< meta name = "author" content = "R74n" >
< link href = "https://fonts.googleapis.com/css?family=Press+Start+2P" rel = "stylesheet" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< script src = "https://R74n.com/load.js" > < / script >
< style >
html, body {
width: 100%;
height: 100%;
margin: 0;
}
body {
font-family: 'Press Start 2P';
background-color: #000000;
color: #ffffff;
}
h1 {
padding: 10px;
2021-12-28 17:44:28 -05:00
padding-bottom: 0px;
2021-12-23 00:21:51 -05:00
}
a {color: rgb(255, 0, 255);text-decoration: none;}
a:hover {color: rgb(255, 121, 255);}
a:active, a:hover:active {color: rgb(255, 179, 255);}
#gameDiv { /*game canvas*/
border: 1px solid #ffffff;
position: absolute;
left: 50%;
transform: translate(-50%, -0%);
-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;
}
2021-12-28 17:44:28 -05:00
#infoScreen {
border: 1px solid #ffffff;
position: absolute;
left: 50%;
transform: translate(-50%, 8%);
width: 95%;
height: 50%;
max-width: 700px;
padding: 10px;
background-color: rgb(31, 31, 31);
display: none;
overflow-x: scroll;
}
#infoTitle {
font-size: 1.5em;
text-decoration: underline;
}
#infoText {
margin-top: 15px;
white-space: pre-wrap;
line-height: 1.5em;
}
#infoX {
position: absolute;
right: 0px;
top: 0px;
font-size: 2em;
background-color: rgb(100, 33, 33);
padding:5px;
text-align:center;
border: 1px solid #ffffff;
}
#infoX:hover {
background-color: rgb(200, 33, 33);
}
#infoSearch {
position: absolute;
bottom: 0px;
width: 100%;
height: 50px;
left: 50%;
transform: translate(-50%, 0%);
background-color: rgb(66, 66, 66);
color: white;
font-size: 1.5em;
padding: 10px;
font-family: 'Press Start 2P';
}
#infoSearch:focus {
outline: none;
}
.infoLink {
color: rgb(116, 140, 221);
cursor: pointer;
text-decoration: underline;
}
2021-12-23 00:21:51 -05:00
button, input[type="submit"], input[type="reset"] {
background: none;
color: inherit;
border: none;
padding: 0;
font: inherit;
cursor: pointer;
outline: inherit;
}
#underBox {
position: absolute;
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.75);
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.75);
}
/*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 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 5px 5px;
font-size: 0.75em;
height: 2em;
}
#stat-pos, #stat-pixels, #stat-shift, #stat-tps, #stat-ticks {
float:left;
}
.categoryName {
font-size: 0.75em;
text-transform: uppercase;
margin-left: 5px;
vertical-align: middle;
}
#extraInfo {
margin:5px
}
2021-12-28 17:44:28 -05:00
#categoryControls {
margin-top: 5px;
margin-bottom: 5px;
background-color: rgba(255, 255, 255, 0.125);
white-space: nowrap;
overflow-x: scroll;
overflow-y: hidden;
width: 100%;
position: absolute;
z-index: 0;
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:1;
}
#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);
}
/* Dark Gray X Scrollbar for categoryControls */
#categoryControls::-webkit-scrollbar {
width: 5px;
height: 8px;
background-color: rgba(255, 255, 255, 0.15);
}
#categoryControls::-webkit-scrollbar-thumb {
background-color: rgba(255, 255, 255, 0.25);
border-radius: 5px;
}
#categoryControls::-webkit-scrollbar-track {
box-shadow: inset 0 0 5px rgba(255, 255, 255, 0.15);
border-radius: 10px;
}
#categoryControls::-webkit-scrollbar-thumb:hover {
background-color: rgba(255, 255, 255, 0.3);
}
.category {
margin-top:3.1em;
position:relative;
display:flex;
flex-direction: column;
flex-wrap:wrap;
text-align:center;
}
2021-12-23 00:21:51 -05:00
< / style >
< 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);};}
< / script >
< script >
2021-12-25 21:02:02 -05:00
2021-12-23 00:21:51 -05:00
behaviors = {
"POWDER": [
"XX|XX|XX",
"XX|XX|XX",
"M2|M1|M2",
],
"AGPOWDER": [
"M2|M1|M2",
"XX|XX|XX",
"XX|XX|XX",
],
"LIQUID": [
"XX|XX|XX",
"M2|XX|M2",
"M1|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",
2021-12-29 20:57:33 -05:00
"XX|M2|XX",
2021-12-23 00:21:51 -05:00
],
"GAS": [
"M2|M1|M2",
"M1|XX|M1",
"M2|M1|M2",
],
"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",
],
2021-12-29 20:57:33 -05:00
"CLONER": [
"XX|CF|XX",
"CF|XX|CF",
"XX|CF|XX",
],
2021-12-23 00:21:51 -05:00
"STURDYPOWDER": [
"XX|XX|XX",
"XX|XX|XX",
"XX|M1|XX",
],
"SELFDELETE": [
"XX|XX|XX",
"XX|DL|XX",
"XX|XX|XX",
],
"FOAM": [
"SW:water%10|SW:water%10|SW:water%10",
"XX|DL%5|XX",
"M2%25|M1%25|M2%25",
],
"BUBBLE": [
"SW:water%25|SW:water%25|SW:water%25",
"M1%5|DL%0.25|M1%5",
"M1%2|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",
],
}
2021-12-25 21:02:02 -05:00
eLists = {
2021-12-29 20:57:33 -05:00
"ANIMAL": ["flea","ant","fly","firefly","bee","frog","fish","worm","termite","rat","slug","snail"],
2021-12-25 21:02:02 -05:00
"CLEANANIMAL": ["ant","firefly","bee","frog","fish"],
}
2021-12-23 00:21:51 -05:00
airDensity = 1.225; // kg/m^3
airTemp = 20; // Celsius
2021-12-28 17:44:28 -05:00
// Element Properties
// * = required
// name - display name of the element
// color - color of the element's pixel *
// behavior - behavior of the element *
// density - density of the element [only used for movable elements] (kg/m^3)
// state - solid, liquid, or gas [only used for movable elements]
2021-12-23 00:21:51 -05:00
// temp - default temperature of the element (Celsius)
2021-12-28 17:44:28 -05:00
// tempHigh - highest temperature before state change (Celsius)
// tempLow - lowest temperature before state change (Celsius)
2021-12-23 00:21:51 -05:00
// 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)
2021-12-28 17:44:28 -05:00
// 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
2021-12-23 00:21:51 -05:00
elements = {
2021-12-30 13:27:16 -05:00
"heat": { //hard-coded
2021-12-23 00:21:51 -05:00
"color": "#ff0000",
"behavior": behaviors.WALL,
"temp": 2,
"category": "tools",
},
2021-12-30 13:27:16 -05:00
"cool": { //hard-coded
2021-12-23 00:21:51 -05:00
"color": "#0000ff",
"behavior": behaviors.WALL,
"temp": -2,
"category": "tools",
},
2021-12-30 13:27:16 -05:00
"erase": { //hard-coded
2021-12-23 00:21:51 -05:00
"color": "#fdb5ff",
"behavior": behaviors.WALL,
"category": "tools",
},
2021-12-30 13:27:16 -05:00
"pick": { //hard-coded
2021-12-23 00:21:51 -05:00
"color": ["#fa9b9b","#fae99b","#9bfab7","#9b9dfa"],
"behavior": behaviors.WALL,
"category": "tools",
},
2021-12-30 13:27:16 -05:00
"mix": { //hard-coded
2021-12-28 17:44:28 -05:00
"color": ["#fff4b5","#a6a6a6"],
"behavior": behaviors.WALL,
"category": "tools",
},
2021-12-30 13:27:16 -05:00
"lookup": { //hard-coded
2021-12-28 17:44:28 -05:00
"color": ["#919c9c","#72abab","#919c9c"],
"behavior": behaviors.WALL,
"category": "tools",
},
2021-12-23 00:21:51 -05:00
"sand": {
"color": "#e6d577",
"behavior": behaviors.POWDER,
"tempHigh": 1700,
"stateHigh": "molten_glass",
"category": "land",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1602,
2021-12-23 00:21:51 -05:00
},
"water": {
"color": "#2167ff",
"behavior": behaviors.LIQUID,
"tempHigh": 100,
"stateHigh": "steam",
"tempLow": 0,
"stateLow": "ice",
"viscosity": 1,
"category": "liquids",
2021-12-28 17:44:28 -05:00
"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", },
"salt": { "elem1": "salt_water", "elem2": null, },
"sugar": { "elem1": "sugar_water", "elem2": null, },
2021-12-29 20:57:33 -05:00
"quicklime": { "elem1": null, "elem2": "slaked_lime", },
2021-12-28 17:44:28 -05:00
},
"state": "liquid",
"density": 997,
},
"salt_water": {
"color": "#4d85ff",
"behavior": behaviors.LIQUID,
"tempHigh": 102,
"stateHigh": "steam",
"tempLow": -2,
"stateLow": "ice",
"viscosity": 2,
"category": "liquids",
"reactions": {
"dirt": { "elem1": null, "elem2": "mud" },
"sand": { "elem1": null, "elem2": "wet_sand", },
},
"state": "liquid",
"density": 1026,
},
"sugar_water": {
"color": "#8eaae6",
"behavior": behaviors.LIQUID,
"tempHigh": 105,
"stateHigh": "steam",
"tempLow": -5,
"stateLow": "ice",
"viscosity": 5,
"category": "liquids",
"reactions": {
"dirt": { "elem1": null, "elem2": "mud" },
"sand": { "elem1": null, "elem2": "wet_sand", },
},
"hidden": true,
"state": "liquid",
"density": 1026,
2021-12-23 00:21:51 -05:00
},
"dirt": {
"color": ["#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#9e6b4b","#b0a39b"],
"behavior": behaviors.POWDER,
"tempHigh":1200,
"tempLow": -50,
"stateLow": "permafrost",
"category":"land",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1220,
},
"mud": {
"color": "#382417",
"behavior": behaviors.STURDYPOWDER,
"tempHigh": 100,
"stateHigh": "mudstone",
2021-12-29 20:57:33 -05:00
"tempLow": -50,
"stateLow": "permafrost",
2021-12-28 17:44:28 -05:00
"category": "land",
"state": "solid",
"density": 1730,
},
"mudstone": {
"color": "#4a341e",
"behavior": behaviors.SUPPORT,
"tempHigh":1200,
"stateHigh": "molten_dirt",
"category": "land",
"state": "solid",
"density": 1250,
},
"wet_sand": {
"color": "#b5a85e",
"behavior": behaviors.STURDYPOWDER,
"tempHigh": 100,
"stateHigh": "packed_sand",
"category": "land",
"state": "solid",
"density": 1905,
},
"packed_sand": {
"color": "#948b5a",
"behavior": behaviors.SUPPORT,
"tempHigh":1700,
"stateHigh": "molten_glass",
"category": "land",
"state": "solid",
"density": 1682,
2021-12-23 00:21:51 -05:00
},
"plant": {
"color": "#00bf00",
2021-12-28 17:44:28 -05:00
"behavior": behaviors.WALL,
2021-12-23 00:21:51 -05:00
"category":"life",
2021-12-23 23:42:03 -05:00
"tempHigh": 300,
"stateHigh": "fire",
2021-12-23 00:21:51 -05:00
"burn":65,
"burnTime":50,
},
"grass": {
"color": "#00ff00",
"behavior": [
"XX|XX|XX",
"XX|XX|XX",
"XX|M1|XX",
],
"tempHigh": 400,
"stateHigh": "fire",
"burn":50,
"burnTime":20,
"category":"land",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1400,
2021-12-23 00:21:51 -05:00
},
"wall": {
"color": "#808080",
"behavior": behaviors.WALL,
"category": "solids",
2021-12-24 00:10:37 -05:00
"insulate": true,
2021-12-23 00:21:51 -05:00
},
"fire": {
"color": ["#ff6b21","#ffa600","#ff4000"],
"behavior": behaviors.UL_UR,
2021-12-29 20:57:33 -05:00
"reactions": {
"water": { "elem1": "smoke" },
},
2021-12-28 17:44:28 -05:00
"temp":600,
"tempLow":100,
2021-12-23 00:21:51 -05:00
"stateLow": "smoke",
2021-12-29 20:57:33 -05:00
"tempHigh": 7000,
2021-12-23 00:21:51 -05:00
"stateHigh": "plasma",
"category": "energy",
"burning": true,
"burnTime": 25,
"burnInto": "smoke",
2021-12-28 17:44:28 -05:00
"state": "gas",
"density": 1180,
2021-12-23 00:21:51 -05:00
},
"steam": {
"color": "#abd6ff",
"behavior": behaviors.GAS,
"temp": 100,
"tempLow": 95,
"stateLow": "water",
"category": "gases",
2021-12-28 17:44:28 -05:00
"state": "gas",
"density": 0.6,
2021-12-23 00:21:51 -05:00
},
"ice": {
"color": "#c5e9f0",
"behavior": behaviors.WALL,
"temp": 0,
"tempHigh": 5,
"stateHigh": "water",
"category": "solids",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 917,
2021-12-23 00:21:51 -05:00
},
"snow": {
"color": "#e1f8fc",
"behavior": behaviors.POWDER,
"temp": 0,
"tempHigh": 5,
"stateHigh": "water",
"category": "land",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 100,
2021-12-23 00:21:51 -05:00
},
"packed_snow": {
"color": "#bcdde3",
"behavior": behaviors.SUPPORTPOWDER,
"temp": 0,
"tempHigh": 20,
"stateHigh": "water",
"category": "land",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 400,
2021-12-23 00:21:51 -05:00
},
"wood": {
"color": "#a0522d",
"behavior": behaviors.WALL,
"tempHigh": 400,
"stateHigh": "fire",
"category": "solids",
"burn": 5,
"burnTime": 300,
"burnInto": ["ash","charcoal","fire"],
2021-12-28 17:44:28 -05:00
"state": "solid",
2021-12-23 00:21:51 -05:00
},
2021-12-23 01:21:38 -05:00
"pollen": {
"color": "#ffffc0",
2021-12-23 16:53:13 -05:00
"behavior": [
"XX|XX|XX",
"XX|CH:flower_seed%0.01|XX",
"M2|M1|M2",
],
2021-12-28 19:02:21 -05:00
"reactions": {
"sugar_water": { "elem1": null, "elem2": "honey" },
},
2021-12-23 01:21:38 -05:00
"category":"life",
"hidden": true,
2021-12-23 16:53:13 -05:00
"burn":50,
"burnTime":20,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1435,
2021-12-23 01:21:38 -05:00
},
2021-12-23 00:21:51 -05:00
"smoke": {
"color": "#383838",
"behavior": behaviors.DGAS,
"temp": 114,
"tempHigh": 605,
"stateHigh": "fire",
"deleteAfter": 100,
"category": "gases",
2021-12-28 17:44:28 -05:00
"state": "gas",
"density": 1180,
2021-12-23 00:21:51 -05:00
},
"rock": {
"color": ["#808080","#4f4f4f","#949494"],
"behavior": behaviors.POWDER,
"tempHigh": 950,
"stateHigh": "magma",
"category": "land",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 2550,
2021-12-23 00:21:51 -05:00
},
"magma": {
"color": ["#ff6f00","#ff8c00","#ff4d00"],
"behavior": behaviors.MOLTEN,
2021-12-29 20:57:33 -05:00
"reactions": {
"ice": { "elem1": "basalt" },
},
2021-12-23 00:21:51 -05:00
"temp": 950,
"tempLow": 800,
"stateLow": "rock",
"viscosity": 10000,
"category": "liquids",
2021-12-28 17:44:28 -05:00
"state": "liquid",
"density": 2725,
2021-12-23 00:21:51 -05:00
},
"concrete": {
"color": "#ababab",
"behavior": behaviors.SUPPORT,
"tempHigh": 1500,
"stateHigh": "magma",
"category": "structure",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 2400,
2021-12-23 00:21:51 -05:00
},
"plasma": {
"color": ["#8800ff","#b184d9","#8800ff"],
2021-12-28 17:44:28 -05:00
"behavior": behaviors.DGAS,
2021-12-29 20:57:33 -05:00
"temp":7065,
"tempLow":5000,
2021-12-23 00:21:51 -05:00
"stateLow": "fire",
"category": "energy",
2021-12-28 17:44:28 -05:00
"state": "gas",
"density": 1,
2021-12-23 00:21:51 -05:00
},
"iron": {
"color": "#cbcdcd",
"behavior": behaviors.WALL,
"tempHigh": 1538,
"category": "solids",
2021-12-28 17:44:28 -05:00
"density": 7860,
},
"rust": {
"color": "#bd6d35",
"behavior": behaviors.SUPPORT,
"tempHigh": 1538,
"stateHigh": "molten_iron",
"category": "solids",
"state": "solid",
"density": 5250,
2021-12-23 00:21:51 -05:00
},
"glass": {
"color": "#5e7c80",
"behavior": behaviors.WALL,
"tempHigh": 1500,
"category": "solids",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 2500,
2021-12-23 00:21:51 -05:00
},
"glass_shard": {
2021-12-28 17:44:28 -05:00
"color": ["#5e7c80","#6299a1","#596b6e"],
2021-12-23 00:21:51 -05:00
"behavior": behaviors.POWDER,
"tempHigh": 1500,
"stateHigh": "molten_glass",
"category": "structure",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 2500,
2021-12-23 00:21:51 -05:00
},
"blood": {
"color": "#ff0000",
"behavior": behaviors.LIQUID,
"viscosity": 10,
"category":"liquids",
2021-12-28 17:44:28 -05:00
"state": "liquid",
"density": 1060,
2021-12-23 00:21:51 -05:00
},
"honey": {
"color": ["#ffd700","#ffae00"],
"behavior": behaviors.LIQUID,
"viscosity": 10000,
"category":"liquids",
2021-12-28 17:44:28 -05:00
"state": "liquid",
"density": 1420,
2021-12-23 00:21:51 -05:00
},
"ketchup": {
"color": "#ff3119",
"behavior": behaviors.LIQUID,
"viscosity": 50000,
"category":"liquids",
2021-12-28 17:44:28 -05:00
"state": "liquid",
"density": 1235,
2021-12-23 00:21:51 -05:00
},
"molasses": {
"color": "#240f00",
"behavior": behaviors.LIQUID,
"viscosity": 7500,
"category":"liquids",
2021-12-28 17:44:28 -05:00
"state": "liquid",
"density": 1600,
2021-12-23 00:21:51 -05:00
},
2021-12-29 20:57:33 -05:00
"cloner": {
"color": "#dddd00",
"behavior": behaviors.CLONER,
"category":"machines",
"insulate":true,
},
"slow_cloner": {
"color": "#888800",
"behavior": [
"XX|CF%10|XX",
"CF%10|XX|CF%10",
"XX|CF%10|XX",
],
"category":"machines",
"insulate":true,
},
2021-12-23 00:21:51 -05:00
"filler": {
"color": "#ae4cd9",
"behavior": behaviors.FILL,
"category":"special",
},
2021-12-29 20:57:33 -05:00
"lattice": {
"color": "#ae4cd9",
"behavior": [
"CL|XX|CL",
"XX|XX|XX",
"CL|XX|CL",
],
"category":"special",
},
2021-12-23 00:21:51 -05:00
"gravel": {
"color": "#454b51",
"behavior": behaviors.POWDER,
"category":"land",
"tempHigh": 950,
"stateHigh": "magma",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1680,
2021-12-23 00:21:51 -05:00
},
"slime": {
"color": "#81cf63",
"behavior": behaviors.LIQUID,
"viscosity": 5000,
"category":"liquids",
2021-12-28 17:44:28 -05:00
"state": "liquid",
"density": 1450,
2021-12-23 00:21:51 -05:00
},
"ruins": {
"color": "#5c5c5c",
"behavior": [
"XX|SP|XX",
"XX|XX|XX",
"M2%1|M1|M2%1"
],
2021-12-28 17:44:28 -05:00
"tempHigh": 1500,
"stateHigh": "magma",
2021-12-23 00:21:51 -05:00
"category":"structure",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 2400,
2021-12-23 00:21:51 -05:00
},
"void": {
"color": "#262626",
"behavior": behaviors.DELETE,
"category":"special",
},
"flea": {
"color": "#9e4732",
"behavior": [
"M2|XX|M2",
"DL:blood|XX|DL:blood",
2021-12-28 21:27:54 -05:00
"M2|DL:blood%25 AND M1|M2",
2021-12-23 00:21:51 -05:00
],
"tempHigh": 35,
"stateHigh": "ash",
"category":"life",
"burn":95,
"burnTime":25,
2021-12-28 17:44:28 -05:00
"state": "solid",
2021-12-23 00:21:51 -05:00
},
"ant": {
"color": "#4a0903",
"behavior": [
"SW:dirt,sand,gravel%5|XX|SW:dirt,sand,gravel%5",
"M2|XX|M2",
"SW:dirt,sand,gravel%5|M1|SW:dirt,sand,gravel%5",
],
"tempHigh": 53.7,
"stateHigh": "ash",
"category":"life",
"burn":95,
"burnTime":25,
2021-12-28 17:44:28 -05:00
"state": "solid",
2021-12-23 00:21:51 -05:00
},
"fly": {
"color": "#303012",
"behavior": [
"M1|M2|M1",
"DL:plant,meat,cooked_meat|XX|DL:plant,meat,cooked_meat",
"M1|M2|M1",
],
"tempHigh": 47,
"stateHigh": "ash",
"category":"life",
"burn":95,
"burnTime":25,
2021-12-28 17:44:28 -05:00
"state": "solid",
2021-12-23 00:21:51 -05:00
},
"firefly": {
"color": ["#303012","#303012","#d9d950","#303012","#303012"],
"behavior": [
"M1|M2|M1",
"XX|CC:303012,303012,303012,303012,d9d950%10|XX",
"M1|M2|M1",
],
"tempHigh": 47,
"stateHigh": "ash",
"category":"life",
"burn":95,
"burnTime":25,
2021-12-28 17:44:28 -05:00
"state": "solid",
2021-12-23 00:21:51 -05:00
},
"bee": {
"color": "#c4b100",
"behavior": [
"M1|M2|M1",
2021-12-23 01:21:38 -05:00
"CR:pollen%0.025 AND M1|XX|CR:pollen%0.025 AND M1",
2021-12-23 00:21:51 -05:00
"M1|M2|M1",
],
"tempHigh": 47,
"stateHigh": "ash",
"category":"life",
"burn":95,
"burnTime":25,
2021-12-28 17:44:28 -05:00
"state": "solid",
2021-12-23 00:21:51 -05:00
},
"frog": {
"color": "#607300",
"behavior": [
"M2%3|CR:slime%0.01|M2%3",
"DL:fly,firefly|XX|DL:fly,firefly",
"XX|M1|XX",
],
"temp": 19.1,
"tempHigh": 41,
"stateHigh": "meat",
"tempLow": -18,
"stateLow": "frozen_frog",
"category":"life",
"burn":75,
"burnTime":30,
2021-12-28 17:44:28 -05:00
"state": "solid",
2021-12-29 20:57:33 -05:00
"density": 1450,
2021-12-23 00:21:51 -05:00
},
"frozen_frog": {
"color": "#007349",
"behavior": behaviors.STURDYPOWDER,
"temp": -18,
"tempHigh": 0,
"stateHigh": "frog",
"tempLow": -18,
"stateLow": "frozen_frog",
"category":"life",
"hidden": true,
2021-12-28 17:44:28 -05:00
"state": "solid",
2021-12-29 20:57:33 -05:00
"density": 1500,
2021-12-23 00:21:51 -05:00
},
"fish": {
"color": "#ac8650",
"behavior": [
2021-12-30 13:27:16 -05:00
"SW:water,salt_water,sugar_water%6|M2%5|SW:water,salt_water,sugar_water%6",
2021-12-23 00:21:51 -05:00
"DL:algae|XX|DL:algae",
2021-12-30 13:27:16 -05:00
"SW:water,salt_water,sugar_water%8|M1|SW:water,salt_water,sugar_water%8",
2021-12-23 00:21:51 -05:00
],
"temp": 20,
"tempHigh": 32,
"stateHigh": "meat",
2021-12-28 17:44:28 -05:00
"tempLow": -20,
"stateLow": "frozen_meat",
2021-12-23 00:21:51 -05:00
"category":"life",
"burn":40,
"burnTime":100,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1080,
2021-12-23 00:21:51 -05:00
},
"algae": {
"color": "#00870e",
"behavior": [
"XX|XX|XX",
2021-12-30 13:27:16 -05:00
"SW:water,salt_water,sugar_water%1|XX|SW:water,salt_water,sugar_water%1",
"SW:water,salt_water,sugar_water%10|M1|SW:water,salt_water,sugar_water%18",
2021-12-23 00:21:51 -05:00
],
2021-12-28 17:44:28 -05:00
"reactions": {
"wood": { "elem1":"lichen" }
},
2021-12-23 00:21:51 -05:00
"category":"life",
"burn":95,
"burnTime":20,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 920,
2021-12-23 00:21:51 -05:00
},
"heater": {
"color": "#881111",
"behavior": [
2021-12-24 00:10:37 -05:00
"XX|HT:2|XX",
"HT:2|XX|HT:2",
"XX|HT:2|XX",
2021-12-23 00:21:51 -05:00
],
"category":"machines",
2021-12-24 00:10:37 -05:00
"insulate":true,
2021-12-23 00:21:51 -05:00
},
"cooler": {
"color": "#111188",
"behavior": [
2021-12-24 00:10:37 -05:00
"XX|CO:2|XX",
"CO:2|XX|CO:2",
"XX|CO:2|XX",
2021-12-23 00:21:51 -05:00
],
"category":"machines",
2021-12-24 00:10:37 -05:00
"insulate":true,
2021-12-23 00:21:51 -05:00
},
"superheater": {
"color": "#dd1111",
"behavior": [
"XX|HT:10|XX",
"HT:10|XX|HT:10",
"XX|HT:10|XX",
],
"category":"machines",
2021-12-24 00:10:37 -05:00
"insulate":true,
2021-12-23 00:21:51 -05:00
},
"freezer": {
"color": "#1111dd",
"behavior": [
"XX|CO:10|XX",
"CO:10|XX|CO:10",
"XX|CO:10|XX",
],
"category":"machines",
2021-12-24 00:10:37 -05:00
"insulate":true,
2021-12-23 00:21:51 -05:00
},
"torch": {
"color": "#d68542",
"behavior": [
"XX|CR:fire|XX",
"XX|XX|XX",
"XX|XX|XX",
],
2021-12-28 17:44:28 -05:00
"temp":600,
2021-12-23 00:21:51 -05:00
"category":"special",
},
"water_spout": {
"color": "#606378",
"behavior": [
"XX|CR:water|XX",
"CR:water|XX|CR:water",
"XX|CR:water|XX",
],
"category":"special",
},
"bone_marrow": {
"color": "#c97265",
"behavior": [
"XX|CR:blood,bone,bone%5|XX",
"CR:blood,bone,bone%5|XX|CR:blood,bone,bone%5",
"XX|CR:blood,bone,bone%5|XX",
],
"category":"life",
2021-12-29 20:57:33 -05:00
"tempHigh": 760,
"stateHigh": "calcium",
2021-12-23 00:21:51 -05:00
"hidden": true,
},
"bone": {
"color": "#d9d9d9",
"behavior": behaviors.SUPPORT,
"category":"life",
2021-12-29 20:57:33 -05:00
"tempHigh": 760,
"stateHigh": "calcium",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1900,
2021-12-23 00:21:51 -05:00
},
"anti_powder": {
"color": "#ebd1d8",
"behavior": behaviors.AGPOWDER,
"category":"special",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1850,
2021-12-23 00:21:51 -05:00
},
"anti_fluid": {
"color": "#d1dbeb",
"behavior": behaviors.AGLIQUID,
"category":"special",
2021-12-28 17:44:28 -05:00
"state": "liquid",
"density": 1000,
2021-12-23 00:21:51 -05:00
},
"vertical": {
"color": "#d9d9d9",
"behavior": [
"XX|M1|XX",
"CR:wall|XX|CR:wall",
"XX|XX|XX",
],
"category":"special",
"hidden":true,
},
"horizontal": {
"color": "#d9d9d9",
"behavior": [
"XX|CR:wall|XX",
"XX|XX|M1",
"XX|CR:wall|XX",
],
"category":"special",
"hidden":true,
},
"rain_cloud": {
"color": "#636b78",
"behavior": [
"XX|XX|XX",
2021-12-29 20:57:33 -05:00
"M1%5|CH:water%0.05|M1%5",
"XX|XX|XX",
2021-12-23 00:21:51 -05:00
],
"category":"special",
2021-12-29 20:57:33 -05:00
"temp": 80,
"tempLow": 0,
"stateLow": "snow_cloud",
"state": "gas",
"density": 1,
2021-12-23 00:21:51 -05:00
},
"snow_cloud": {
"color": "#7e8691",
"behavior": [
"XX|XX|XX",
2021-12-29 20:57:33 -05:00
"M1%5|CH:snow%0.05|M1%5",
"XX|XX|XX",
2021-12-23 00:21:51 -05:00
],
"category":"special",
2021-12-29 20:57:33 -05:00
"temp": -10,
"tempHigh": 30,
"stateHigh": "rain_cloud",
"state": "gas",
"density": 2,
2021-12-23 00:21:51 -05:00
},
"acid_cloud": {
"color": "#637865",
"behavior": [
"XX|XX|XX",
2021-12-29 20:57:33 -05:00
"M1%5|CH:acid%0.05|M1%5",
"XX|XX|XX",
2021-12-23 00:21:51 -05:00
],
"category":"special",
2021-12-29 20:57:33 -05:00
"density": 3,
2021-12-23 00:21:51 -05:00
},
"rocket": {
"color": "#ff0000",
"behavior": [
"XX|M1|XX",
"XX|XX|XX",
"XX|CR:fire|XX",
],
"hidden":true,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 7300,
2021-12-23 00:21:51 -05:00
},
"ash": {
"color": ["#8c8c8c","#9c9c9c"],
"behavior": behaviors.POWDER,
"category":"energy",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 700,
2021-12-23 00:21:51 -05:00
},
"meat": {
"color": "#b86565",
"behavior": [
"XX|XX|XX",
"SP|CH:rotten_meat%0.005|SP",
"XX|M1|XX",
],
"tempHigh": 80,
"stateHigh": "cooked_meat",
"tempLow": -18,
"stateLow": "frozen_meat",
"category":"life",
"burn":25,
"burnTime":200,
"burnInto":"cooked_meat",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1019.5,
2021-12-23 00:21:51 -05:00
},
"rotten_meat": {
"color": ["#9ab865","#b8b165","#b89765"],
"behavior": [
"XX|CR:plague%0.25|XX",
"SP|XX|SP",
"XX|M1|XX",
],
"tempHigh": 120,
"stateHigh": "plague",
"category":"life",
"hidden": true,
"burn":25,
"burnTime":200,
"burnInto":"plague",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1005,
2021-12-23 00:21:51 -05:00
},
"cooked_meat": {
"color": "#61361c",
"behavior": behaviors.STURDYPOWDER,
"tempHigh": 120,
"stateHigh": "ash",
"category":"life",
"hidden":true,
"burn":25,
"burnTime":200,
"burnInto": "ash",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1005,
2021-12-23 00:21:51 -05:00
},
"frozen_meat": {
"color": "#65b8aa",
"behavior": behaviors.STURDYPOWDER,
"temp": -18,
"tempHigh": 0,
"stateHigh": "meat",
"category":"life",
"hidden":true,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1067.5,
2021-12-23 00:21:51 -05:00
},
"light": {
"color": "#ffffa8",
"behavior": behaviors.SELFDELETE,
2021-12-29 20:57:33 -05:00
"temp": 40,
2021-12-23 00:21:51 -05:00
"category":"energy",
},
"pointer": {
"color": "#ff0000",
"behavior": behaviors.SELFDELETE,
"category":"tools",
"hidden":true,
},
"charcoal": {
"color": "#2b2b2b",
"behavior": behaviors.POWDER,
"burn": 25,
"burnTime": 1000,
"burnInto": "carbon_dioxide",
"category": "energy",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 208,
},
"hydrogen": {
"color": "#558bcf",
"behavior": behaviors.GAS,
"reactions": {
"oxygen": { "elem1":null, "elem2":"steam" },
},
"category": "gases",
"burn": 100,
"burnTime": 2,
"tempLow": -252.8,
"stateLow": "liquid_hydrogen",
"state": "gas",
2021-12-29 20:57:33 -05:00
"density": 0.08375,
2021-12-28 17:44:28 -05:00
},
"oxygen": {
"color": "#99c7ff",
"behavior": behaviors.GAS,
"reactions": {
"copper": { "elem2":"oxidized_copper" },
"iron": { "elem2":"rust" },
},
"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" },
},
"category": "gases",
"tempLow": -195.8,
"stateLow": "liquid_nitrogen",
"state": "gas",
"density": 1.165,
},
"anesthesia": {
"color": "#d3e1e3",
"behavior": behaviors.LIQUID,
"category": "liquids",
"hidden": true,
"state": "liquid",
"density": 1.9781,
},
"liquid_hydrogen": {
"color": "#97afcf",
"behavior": behaviors.LIQUID,
"reactions": {
"liquid_oxygen": { "elem1":"ice", "elem2":null },
"oxygen": { "elem1":"ice", "elem2":null },
},
"category": "liquids",
"burn": 100,
"burnTime": 2,
"temp":-252.8,
"tempHigh": -252.8,
"stateHigh": "hydrogen",
"state": "liquid",
"density": 71,
},
"liquid_oxygen": {
"color": "#00ad99",
"behavior": behaviors.LIQUID,
"reactions": {
"hydrogen": { "elem1":"ice", "elem2":null },
},
"category": "liquids",
"burn": 100,
"burnTime": 2,
"temp":-182.94,
"tempHigh": -182.94,
"stateHigh": "oxygen",
"state": "liquid",
"density": 1141,
},
"liquid_nitrogen": {
"color": "#d3e1e3",
"behavior": behaviors.LIQUID,
"category": "liquids",
"temp":-195.8,
"tempHigh": -195.8,
"stateHigh": "nitrogen",
"state": "liquid",
"density": 804,
2021-12-23 00:21:51 -05:00
},
"carbon_dioxide": {
"color": "#2f2f2f",
"behavior": behaviors.GAS,
2021-12-28 17:44:28 -05:00
"reactions": {
"plant": { "elem1":"oxygen" },
"algae": { "elem1":"oxygen" },
},
2021-12-23 00:21:51 -05:00
"category": "gases",
"tempLow": -78.5,
"stateLow": "dry_ice",
2021-12-28 17:44:28 -05:00
"state": "gas",
"density": 1.977,
2021-12-23 00:21:51 -05:00
},
"dry_ice": {
"color": "#e6e6e6",
"behavior": behaviors.WALL,
"category": "solids",
"temp": -78.5,
"tempHigh": -78.5,
"stateHigh": "carbon_dioxide",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1562,
2021-12-23 00:21:51 -05:00
},
"oil": {
"color": "#300000",
"behavior": behaviors.LIQUID,
"category": "liquids",
"tempHigh": 400,
"stateHigh": "fire",
"burn": 100,
"burnTime": 30,
"burnInto": ["carbon_dioxide","fire"],
"viscosity": 250,
2021-12-28 17:44:28 -05:00
"state": "liquid",
"density": 825,
2021-12-23 00:21:51 -05:00
},
"lamp_oil": {
"color": "#1a0803",
"behavior": behaviors.LIQUID,
"category": "liquids",
"tempHigh": 400,
"stateHigh": "fire",
"burn": 95,
"burnTime": 2000,
"burnInto": ["carbon_dioxide","fire"],
"viscosity": 3,
2021-12-28 17:44:28 -05:00
"state": "liquid",
"density": 850,
2021-12-23 00:21:51 -05:00
},
"propane": {
"color": "#cfcfcf",
"behavior": behaviors.GAS,
"category": "gases",
"tempHigh": 400,
"stateHigh": "fire",
"burn": 100,
"burnTime": 5,
"fireColor": ["#00ffff","#00ffdd"],
2021-12-28 17:44:28 -05:00
"state": "gas",
"density": 2.0098,
2021-12-23 00:21:51 -05:00
},
"methane": {
"color": "#9f9f9f",
"behavior": behaviors.GAS,
"category": "gases",
"tempHigh": 400,
"stateHigh": "fire",
"burn": 85,
"burnTime": 5,
"fireColor": ["#00ffff","#00ffdd"],
2021-12-28 17:44:28 -05:00
"state": "gas",
"density": 0.554,
2021-12-23 00:21:51 -05:00
},
"tinder": {
"color": ["#917256","#87684F","#735F4A","#5D4C3E","#4B3A2E"],
"behavior": behaviors.STURDYPOWDER,
"category": "energy",
"burn": 50,
"burnTime": 100,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 23,
2021-12-23 00:21:51 -05:00
},
"static": {
"color": ["#ffffff","#888888","#000000"],
"behavior": [
"XX|XX|XX",
"XX|CC:ffffff,9c9c9c,454545|XX",
"XX|XX|XX",
],
"category": "special",
},
"borax": {
"color": "#ffffff",
"behavior": behaviors.POWDER,
"burn": 15,
"burnTime": 200,
"fireColor": ["#34eb67","#5ceb34"],
"tempHigh": 743,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1730,
2021-12-23 00:21:51 -05:00
},
2021-12-29 20:57:33 -05:00
"smoke_grenade": {
"color": "#2b382c",
"behavior": [
"XX|CR:smoke|XX",
"XX|XX|XX",
"M2|M1|M2",
],
"state": "solid",
"density": 7300,
},
2021-12-23 00:21:51 -05:00
"bamboo": {
"color": "#336600",
"behavior": behaviors.WALL,
"tempHigh": 400,
"stateHigh": "fire",
"burn": 10,
"burnTime": 200,
"category": "life",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 686,
2021-12-23 00:21:51 -05:00
},
"bamboo_plant": {
"color": "#b4c781",
"behavior": [
"XX|M2%0.25|XX",
"XX|L2:bamboo AND CH:bamboo%0.025|XX",
"XX|M1|XX",
],
"tempHigh": 400,
"stateHigh": "fire",
"burn": 30,
"burnTime": 100,
"category": "life",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 686,
2021-12-23 00:21:51 -05:00
},
"clay": {
"color": "#d4c59c",
"behavior": behaviors.SUPPORT,
"tempHigh": 135,
"stateHigh": "baked_clay",
"category": "land",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1760,
2021-12-23 00:21:51 -05:00
},
"baked_clay": {
"color": "#b85746",
"behavior": behaviors.SUPPORT,
"category": "structure",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 2000,
2021-12-23 00:21:51 -05:00
},
"brick": {
"color": "#cb4141",
"behavior": behaviors.WALL,
2021-12-28 17:44:28 -05:00
"category": "solids",
2021-12-23 00:21:51 -05:00
"tempHigh": 1540,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1650,
2021-12-23 00:21:51 -05:00
},
"sapling": {
"color": "#3e9c3e",
"behavior": [
"XX|M2%2|XX",
"XX|L2:wood,tree_branch AND CH:wood%0.25|XX",
"XX|M1|XX",
],
"tempHigh": 400,
"stateHigh": "fire",
"burn": 65,
"burnTime": 15,
"category": "life",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1500,
2021-12-23 00:21:51 -05:00
},
"grass_seed": {
"color": "#00ff00",
"behavior": [
"XX|M2%0.05|XX",
"XX|L2:grass|XX",
"XX|M1|XX",
],
"tempHigh": 400,
"stateHigh": "fire",
"burn": 50,
"burnTime": 20,
"category": "life",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1400,
2021-12-23 00:21:51 -05:00
},
"wheat_seed": {
"color": "#b6c981",
"behavior": [
"CR:wheat%0.05|M2%0.25|CR:wheat%0.05",
"XX|L2:wheat AND CH:wheat%0.01|XX",
"XX|M1|XX",
],
"tempHigh": 400,
"stateHigh": "fire",
"burn": 50,
"burnTime": 20,
"category": "life",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 769,
2021-12-23 00:21:51 -05:00
},
"wheat": {
"color": "#c9bc81",
"behavior": behaviors.WALL,
2021-12-28 17:44:28 -05:00
"reactions": {
"rock": { "elem1":"flour", "elem2":"rock" }
},
2021-12-23 00:21:51 -05:00
"tempHigh": 400,
"stateHigh": "fire",
"burn":40,
"burnTime":25,
"category":"life",
"hidden":true,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 769,
2021-12-23 00:21:51 -05:00
},
"straw": {
"color": "#c9bc81",
"behavior": behaviors.SUPPORT,
"tempHigh": 400,
"stateHigh": "fire",
"burn": 60,
"burnTime": 40,
"category": "structure",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 67.5,
2021-12-23 00:21:51 -05:00
},
"flower_seed": {
"color": "#0e990e",
"behavior": [
"XX|M2%1.5|XX",
"XX|L2:grass AND CH:pistil%0.3|XX",
"XX|M1|XX",
],
"tempHigh": 400,
"stateHigh": "fire",
"burn":50,
"burnTime":20,
"category":"life",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1400,
2021-12-23 00:21:51 -05:00
},
"pistil": {
"color": "#734e39",
"behavior": [
"XX|CR:petal%10|XX",
"CR:petal%10|XX|CR:petal%10",
"XX|M1|XX",
],
"tempHigh": 400,
"stateHigh": "fire",
"burn":50,
"burnTime":20,
"category":"life",
"hidden": true,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1400,
2021-12-23 00:21:51 -05:00
},
"petal": {
"color": "#ff0000",
"behavior": behaviors.WALL,
"tempHigh": 400,
"stateHigh": "fire",
"burn":50,
"burnTime":20,
"category":"life",
"hidden": true,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1400,
2021-12-23 00:21:51 -05:00
},
"tree_branch": {
"color": "#a0522d",
"behavior": [
"CR:plant,tree_branch%2|CR:plant,plant,plant,tree_branch%2|CR:plant,tree_branch%2",
"XX|XX|XX",
"XX|XX|XX",
],
"tempHigh": 400,
"stateHigh": "fire",
"category": "solids",
"burn": 40,
"burnTime": 50,
"burnInto": ["ash","charcoal","fire"],
"hidden": true,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1500,
2021-12-23 00:21:51 -05:00
},
"vine": {
"color": "#005900",
"behavior": [
"XX|XX|XX",
"XX|XX|XX",
"XX|CL%2.5|XX",
],
"tempHigh": 400,
"stateHigh": "fire",
"burn": 35,
"burnTime": 100,
"category": "life",
2021-12-28 17:44:28 -05:00
"hidden": true,
2021-12-23 00:21:51 -05:00
},
"burner": {
"color": "#d6baa9",
"behavior": [
"CR:propane|CR:propane|CR:propane",
"XX|XX|XX",
"XX|XX|XX",
],
"category": "machines"
},
"foam": {
"color": "#cad2e3",
"behavior": behaviors.FOAM,
2021-12-28 17:44:28 -05:00
"category": "liquids",
"state": "gas",
"density": 40,
2021-12-23 00:21:51 -05:00
},
"bubble": {
"color": "#afc7fa",
"behavior": behaviors.BUBBLE,
2021-12-28 17:44:28 -05:00
"category": "liquids",
"state": "gas",
"density": 1.294,
2021-12-23 00:21:51 -05:00
},
"rainbow": {
"color": ["#ff0000","#ff8800","#ffff00","#00ff00","#00ffff","#0000ff","#ff00ff"],
"behavior": [
"XX|XX|XX",
"XX|CC:ff0000,ff8800,ffff00,00ff00,00ffff,0000ff,ff00ff|XX",
"XX|XX|XX",
],
"category": "special",
},
"copper": {
"color": "#e08128",
"behavior": [
"XX|XX|XX",
"XX|CH:oxidized_copper%0.001|XX",
"XX|XX|XX",
],
"category": "solids",
"tempHigh": 1085,
2021-12-28 17:44:28 -05:00
"density": 8960,
2021-12-23 00:21:51 -05:00
},
"oxidized_copper": {
"color": "#7f9c21",
"behavior": [
"XX|XX|XX",
"XX|XX|XX",
"XX|XX|XX",
],
"category": "solids",
"hidden": true,
"tempHigh": 1085,
"stateHigh": "molten_copper",
2021-12-28 17:44:28 -05:00
"density": 8960,
2021-12-23 00:21:51 -05:00
},
"acid": {
"color": ["#b5cf91","#a1ff5e","#288f2a"],
"behavior": [
"XX|DL%5|XX",
"DL%5 AND M2|DL%2|DL%5 AND M2",
"DL%5 AND M2|DL%10 AND M1|DL%5 AND M2",
],
"category": "liquids",
"burn": 30,
"burnTime": 1,
2021-12-28 17:44:28 -05:00
"state": "liquid",
"density": 1049,
2021-12-23 00:21:51 -05:00
},
"acid_gas": {
"color": ["#c0d1a7","#c2ff96","#58a659"],
"behavior": [
"M1|DL%5 AND M1|M1",
"DL%5 AND M1|DL%2|DL%5 AND M1",
"DL%5 AND M1|DL%10 AND M1|DL%5 AND M1",
],
"category": "gases",
"burn": 30,
"burnTime": 1,
2021-12-28 17:44:28 -05:00
"state": "gas",
"density": 1.63,
2021-12-23 00:21:51 -05:00
},
"dust": {
"color": "#666666",
"behavior": behaviors.POWDER,
"burn": 10,
"burnTime": 1,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1490,
2021-12-23 00:21:51 -05:00
},
"glue": {
"color": "#f0f0f0",
"behavior": behaviors.STICKY,
"category": "liquids",
2021-12-28 17:44:28 -05:00
"state": "liquid",
"density": 1300,
2021-12-23 00:21:51 -05:00
},
"gray_goo": {
"color": "#c0c0c0",
"behavior": [
"XX|CH:gray_goo|XX",
"CH:gray_goo|DL%5|CH:gray_goo",
"XX|CH:gray_goo AND M1|XX",
],
"category": "machines",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 21450,
2021-12-23 00:21:51 -05:00
},
2021-12-29 20:57:33 -05:00
"clone_powder": {
"color": "#f0f000",
"behavior": [
"XX|CF|XX",
"CF|XX|CF",
"M2|CF AND M1|M2",
],
"category":"machines",
"insulate":true,
"state":"solid",
"density":2710,
},
"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",
],
"category":"machines",
"insulate":true,
"state":"solid",
"density":1355,
},
2021-12-23 00:21:51 -05:00
"virus": {
"color": "#cc00ff",
"behavior": [
"XX|CH:virus%25|XX",
"CH:virus%25|XX|CH:virus%25",
"XX|CH:virus%25 AND M1|XX",
],
"category": "special",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 600,
2021-12-23 00:21:51 -05:00
},
"worm": {
"color": "#402208",
"behavior": [
"DL:ash%1 AND SW:dirt,sand,gravel,ash%3|XX|DL:ash%1 AND SW:dirt,sand,gravel,ash%3",
"DL:ash%1 AND M2%10|XX|DL:ash%1 AND M2%10",
"DL:ash%1 AND SW:dirt,sand,gravel,ash%3|M1|DL:ash%1 AND SW:dirt,sand,gravel,ash%3",
],
"tempHigh": 40,
"stateHigh": "ash",
"category":"life",
"burn":95,
"burnTime":25,
2021-12-28 17:44:28 -05:00
"state": "solid",
2021-12-23 00:21:51 -05:00
},
"termite": {
"color": "#f5a056",
"behavior": [
"SW:wood,tree_branch%5|XX|SW:wood,tree_branch%5",
"DL:wood%4 AND M2%15|XX|DL:wood%4 AND M2%15",
"SW:wood,tree_branch%5|M1|SW:wood,tree_branch%5",
],
"tempHigh": 37.78,
"stateHigh": "ash",
"category":"life",
"burn":95,
"burnTime":25,
2021-12-28 17:44:28 -05:00
"state": "solid",
2021-12-23 00:21:51 -05:00
},
"permafrost": {
"color": "#4b9e82",
"behavior": behaviors.SUPPORT,
2021-12-24 00:49:47 -05:00
"temp": -50,
2021-12-23 00:21:51 -05:00
"tempHigh": 0,
2021-12-28 17:44:28 -05:00
"stateHigh": "mud",
2021-12-23 00:21:51 -05:00
"category": "land",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 700,
2021-12-23 00:21:51 -05:00
},
"chocolate": {
"color": "#4d2818",
"behavior": behaviors.STURDYPOWDER,
"tempHigh": 31,
"stateHigh": "chocolate_syrup",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1325,
2021-12-23 00:21:51 -05:00
},
"chocolate_syrup": {
"color": "#5e2412",
"behavior": behaviors.LIQUID,
"tempLow": 0,
"stateLow": "chocolate",
"category": "liquids",
"viscosity": 40,
2021-12-28 17:44:28 -05:00
"state": "liquid",
"density": 1325,
2021-12-23 00:21:51 -05:00
},
"cheese": {
"color": "#fcba03",
"behavior": behaviors.STURDYPOWDER,
"tempHigh": 54,
"stateHigh": "melted_cheese",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1153,
2021-12-23 00:21:51 -05:00
},
"melted_cheese": {
"color": "#fcdb53",
"behavior": behaviors.LIQUID,
"tempLow": 0,
"stateLow": "cheese",
"category": "liquids",
"viscosity": 112,
"hidden": true,
2021-12-28 17:44:28 -05:00
"state": "liquid",
"density": 1153,
2021-12-23 00:21:51 -05:00
},
"fireball": {
"color": "#b52c0d",
"behavior": [
"XX|CR:fire|XX",
"XX|XX|XX",
"M2|M1|M2",
],
"category": "special",
2021-12-28 17:44:28 -05:00
"temp":600,
2021-12-23 00:21:51 -05:00
"burning": true,
"burnInto": "rock",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1600,
2021-12-23 00:21:51 -05:00
},
"mushroom_spore": {
"color": ["#d1d1d1","#d4cfa9","#b4d4ae","#b98aba","#805236"],
"behavior": [
"XX|M2%1.5|XX",
"XX|L2:mushroom_stalk AND CH:mushroom_gill%0.3|XX",
"XX|M1|XX",
],
2021-12-28 17:44:28 -05:00
"reactions": {
"wood": { "elem1":"lichen" }
},
2021-12-23 00:21:51 -05:00
"category": "life",
"burn": 10,
"burnTime": 20,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 123.6,
2021-12-23 00:21:51 -05:00
},
"mushroom_stalk": {
"color": "#d1d1d1",
"behavior": [
"XX|XX|XX",
"XX|XX|XX",
"XX|CH:dirt>hyphae%1|XX",
],
"category": "life",
"hidden": true,
"burn": 10,
"burnTime": 65,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 90.445,
2021-12-23 00:21:51 -05:00
},
"mushroom_gill": {
"color": "#d4cfa9",
"behavior": [
"XX|CR:mushroom_cap%10|XX",
"CR:mushroom_gill,mushroom_cap%2|XX|CR:mushroom_gill,mushroom_cap%2",
"XX|XX|XX",
],
"category": "life",
"hidden": true,
"burn": 10,
"burnTime": 65,
"burnInto": "mushroom_spore",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 90.445,
2021-12-23 00:21:51 -05:00
},
"mushroom_cap": {
"color": ["#c74442","#c74442","#c74442","#c74442","#c74442","#c74442","#cfb4b4"],
"behavior": behaviors.WALL,
"category": "life",
"hidden": true,
"burn": 10,
"burnTime": 65,
"burnInto": "mushroom_spore",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 90.445,
2021-12-23 00:21:51 -05:00
},
"hyphae": {
"color": "#c79789",
"behavior": [
"CH:dirt>hyphae,hyphae,mycelium%0.5|CR:mushroom_spore%0.5|CH:dirt>hyphae,hyphae,mycelium%0.5",
"CH:mycelium%0.5|XX|CH:mycelium%0.5",
"CH:dirt>hyphae,hyphae,mycelium%0.5|XX|CH:dirt>hyphae,hyphae,mycelium%0.5",
],
"category": "life",
"hidden": true,
"burn": 30,
"burnTime": 20,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 462,
2021-12-23 00:21:51 -05:00
},
"mycelium": {
"color": "#734d5e",
"behavior": behaviors.POWDER,
"tempHigh":1200,
"stateHigh": "molten_dirt",
"tempLow": -50,
"stateLow": "permafrost",
"burn": 20,
"burnTime": 40,
"burnInto": "dirt",
"category":"land",
"hidden": true,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 462,
2021-12-23 00:21:51 -05:00
},
"antimatter": {
"color": "#a89ba8",
"behavior": [
"M2|CH:light%50 AND M2|M2",
"M1|DL%2|M1",
"M1|CH:light%50 AND M1|M1",
],
"category": "special",
2021-12-28 17:44:28 -05:00
"state": "gas",
2021-12-23 00:21:51 -05:00
},
"plastic": {
"color": "#c5dede",
"behavior": behaviors.WALL,
2021-12-28 17:44:28 -05:00
"tempHigh": 250,
2021-12-23 00:21:51 -05:00
"burn": 10,
"burnTime": 200,
"burnInto": "dioxin",
"category": "solids",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1052,
2021-12-23 00:21:51 -05:00
},
"dioxin": {
"color": "#b8b8b8",
"behavior": behaviors.GAS,
"category": "gases",
"hidden": true,
2021-12-28 17:44:28 -05:00
"state": "gas",
"density": 1830,
2021-12-23 00:21:51 -05:00
},
"bead": {
"color": ["#ff5e5e","#ffcc5e","#76ff5e","#5ed4ff","#5e61ff","#cf5eff"],
"behavior": behaviors.POWDER,
"tempHigh": 185,
"stateHigh": "molten_plastic",
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1052,
2021-12-23 00:21:51 -05:00
},
"epsom_salt": {
"color": ["#f2f2f2","#e0e0e0"],
"behavior": behaviors.POWDER,
"burn": 40,
"burnTime": 200,
"fireColor": ["#ffffff","#fcf0f0"],
"tempHigh": 1124,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 1680,
2021-12-23 00:21:51 -05:00
},
"potassium_salt": {
"color": ["#f2f2f2","#e0e0e0"],
"behavior": behaviors.POWDER,
"burn": 40,
"burnTime": 200,
"fireColor": ["#ff00ee","#ff6bf5"],
"tempHigh": 292,
2021-12-28 17:44:28 -05:00
"state": "solid",
"density": 3980,
2021-12-23 00:21:51 -05:00
},
"rat": {
"color": "#b8aea5",
"behavior": [
2021-12-28 21:27:54 -05:00
"M2%5|CR:plague%0.5 AND M2%1.5|M2%5",
2021-12-23 00:21:51 -05:00
"M2|XX|M2",
"M2|M1|M2",
],
"category": "life",
"tempHigh": 50,
"stateHigh": "meat",
"tempLow": 15,
"stateLow": "frozen_meat",
"burn":80,
"burnTime":150,
2021-12-28 17:44:28 -05:00
"state": "solid",
2021-12-23 00:21:51 -05:00
},
"plague": {
"color": "#36005c",
"behavior": [
"M2|DL:"+eLists.CLEANANIMAL+" AND M1|M2",
"DL:"+eLists.CLEANANIMAL+" AND M1|XX|DL:"+eLists.CLEANANIMAL+" AND M1",
"M2|DL:"+eLists.CLEANANIMAL+" AND M1|M2",
],
"category": "life",
2021-12-28 17:44:28 -05:00
"state": "gas",
"density": 600,
2021-12-23 00:21:51 -05:00
},
2021-12-24 00:10:37 -05:00
"insulation": {
"color": "#b8aea5",
"behavior": behaviors.WALL,
"category": "structure",
"insulate": true,
2021-12-28 17:44:28 -05:00
"state": "solid",
},
"zinc": {
"color": "#9c9da2",
"behavior": behaviors.WALL,
"tempHigh": 419.53,
"category": "solids",
"density": 7068,
},
"tin": {
"color": "#d3d4d5",
"behavior": behaviors.WALL,
"tempHigh": 231.9,
"category": "solids",
"density": 7260,
},
"nickel": {
"color": "#727472",
"behavior": behaviors.WALL,
"tempHigh": 1455,
"category": "solids",
"density": 8900,
},
"silver": {
"color": "#aaa9ad",
"behavior": behaviors.WALL,
"tempHigh": 961.8,
"category": "solids",
"density": 10497,
},
"gold": {
"color": ["#FFF0B5","#986A1A","#F0BB62"],
"behavior": behaviors.WALL,
"tempHigh": 1064,
"category": "solids",
"density": 19300,
},
"gold_coin": {
"color": ["#FFF0B5","#986A1A","#F0BB62"],
"behavior": behaviors.POWDER,
"tempHigh": 1064,
"stateHigh": "molten_gold",
"state": "solid",
"density": 19300,
},
"aluminum": {
"color": ["#b0afb4","#8c8f98"],
"behavior": behaviors.WALL,
"tempHigh": 660.3,
"category": "solids",
"density": 2710,
},
"lead": {
"color": "#6c6c6a",
"behavior": behaviors.WALL,
"tempHigh": 327.5,
"category": "solids",
"density": 11343,
},
"brass": {
"color": ["#cb9e5d","#865e39"],
"behavior": behaviors.WALL,
"tempHigh": 927,
"category": "solids",
"density": 8550,
},
"bronze": {
"color": "#cd7f32",
"behavior": behaviors.WALL,
"tempHigh": 913,
"category": "solids",
"density": 8150,
},
"sterling": {
"color": ["#858478","#eae8e2","#bfbcb7"],
"behavior": behaviors.WALL,
"tempHigh": 802,
"category": "solids",
"density": 10375.25,
},
"steel": {
"color": "#71797E",
"behavior": behaviors.WALL,
"tempHigh": 1455.5,
"category": "solids",
"density": 7850,
},
"rose_gold": {
"color": ["#B76E79","#a1334d","#f06283"],
"behavior": behaviors.WALL,
"tempHigh": 897,
"category": "solids",
"density": 12900,
},
"solder": {
"color": "#a1a19d",
"behavior": behaviors.WALL,
"tempHigh": 200,
"category": "solids",
"density": 8885,
},
"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_iron": {
"reactions": {
"charcoal": { "elem1": "molten_steel", "elem2": null },
}
},
"molten_tin": {
"reactions": {
"molten_lead": { "elem1": null, "elem2": "molten_solder" },
}
},
"milk": {
"color": "#fafafa",
"behavior": behaviors.LIQUID,
"tempHigh": 93,
"stateHigh": "yogurt",
"viscosity": 1.5,
"category": "liquids",
"state": "liquid",
"density": 1036.86,
},
"yogurt": {
"color": "#f0efe6",
"behavior": behaviors.STURDYPOWDER,
"state": "liquid",
"density": 820.33,
},
"vinegar": {
"color": "#ffecb3",
"behavior": behaviors.LIQUID,
"reactions": {
"milk": { "elem1": null, "elem2": "cheese" },
"baking_soda": { "elem1": "carbon_dioxide", "elem2": "sodium_acetate" },
},
"viscosity": 12,
"category": "liquids",
"state": "liquid",
"density": 1006,
},
"baking_soda": {
"color": "#ededed",
"behavior": behaviors.POWDER,
"state": "solid",
"density": 1000,
},
"sodium_acetate": {
"color": ["#ededed","#dbdbdb"],
"behavior": behaviors.POWDER,
"hidden": true,
"state": "solid",
"density": 900,
},
"udder": {
"color": "#ecb3f5",
"behavior": [
"XX|XX|XX",
"XX|XX|XX",
"XX|CR:milk%5|XX",
],
"category":"life",
},
"corn": {
"color": ["#e0d041","#e6d96a"],
"behavior": behaviors.WALL,
"category": "life",
"burn": 10,
"burnTime": 200,
"tempHigh": 180,
"stateHigh": "popcorn",
"state": "solid",
"density": 721,
},
"popcorn": {
"color": ["#a6a076","#ebe4ab","#ebe4ab","#ebe4ab","#ebe4ab","#ebe4ab","#ebe4ab","#c99947"],
"behavior": behaviors.POWDER,
"burn": 20,
"burnTime": 200,
"state": "solid",
"density": 360.5,
},
"corn_seed": {
"color": "#dfff80",
"behavior": [
"XX|M2%0.25|XX",
"XX|L2:plant,corn AND CH:corn%0.01|XX",
"XX|M1|XX",
],
"tempHigh": 400,
"stateHigh": "fire",
"burn": 50,
"burnTime": 20,
"category": "life",
"state": "solid",
"density": 721,
},
"root": {
"color": "#735949",
"behavior": behaviors.WALL,
"tempHigh": 400,
"stateHigh": "fire",
"burn": 50,
"burnTime": 20,
"burnInto": "dirt",
"category": "life",
"state": "solid",
"density": 1250,
},
"potato_seed": {
"color": "#d9d457",
"behavior": [
"XX|CH:dirt>root|XX",
"CH:dirt>potato%5|CH:potato%1|CH:dirt>potato%5",
"XX|SW:dirt%3 AND M1|XX",
],
"tempHigh": 400,
"stateHigh": "fire",
"burn": 50,
"burnTime": 20,
"category": "life",
"state": "solid",
"density": 675,
},
"potato": {
"color": ["#d99857","#d98757","#a66933"],
"behavior": behaviors.STURDYPOWDER,
"tempHigh": 400,
"stateHigh": "ash",
"burn": 50,
"burnTime": 20,
"burnInto": "ash",
"category": "life",
"state": "solid",
"density": 675,
},
"yeast": {
"color": ["#AD9166","#9A7F4E","#D8BB8D"],
"behavior": [
"XX|CL:50%20|XX",
"CL:50%20 AND SW:bread%30|XX|CL:50%20 AND SW:bread%30",
"XX|M1|XX",
],
"reactions": {
"bread": { "elem1": "bread" },
"sugar": { "elem2": "alcohol" },
"potato": { "elem2": "alcohol" },
},
"tempHigh": 100,
"stateHigh": "bread",
"burn": 50,
"burnTime": 20,
"burnInto": "ash",
"category": "life",
"state": "solid",
"density": 1180,
},
"bread": {
"color": "#F2CF99",
"behavior": behaviors.STURDYPOWDER,
"tempHigh": 176,
"stateHigh": "toast",
"burn": 30,
"burnTime": 200,
"burnInto": "ash",
"state": "solid",
"density": 233.96,
},
"toast": {
"color": "#C08655",
"behavior": behaviors.STURDYPOWDER,
"tempHigh": 500,
"stateHigh": "ash",
"burn": 50,
"burnTime": 170,
"burnInto": "ash",
"state": "solid",
"density": 233.96,
},
"flour": {
"color": "#F0E2B7",
"behavior": behaviors.POWDER,
"reactions": {
"water": { "elem1": "dough", "elem2": null },
},
"tempHigh": 400,
"stateHigh": "fire",
"burn":40,
"burnTime":25,
"state": "solid",
"density": 600,
},
"dough": {
"color": "#EDD8BA",
"behavior": behaviors.SUPPORT,
"tempHigh": 94,
"stateHigh": "bread",
"burn":40,
"burnTime":25,
"burnInto":"ash",
"state": "solid",
"density": 526.9,
},
"salt": {
"color": ["#f2f2f2","#e0e0e0"],
"behavior": behaviors.POWDER,
"tempHigh": 801,
"state": "solid",
2021-12-30 13:27:16 -05:00
"density": 2160,
2021-12-28 17:44:28 -05:00
},
"sugar": {
"color": "#f2f2f2",
"behavior": behaviors.POWDER,
"tempHigh": 186,
"stateHigh": "caramel",
"state": "solid",
2021-12-30 13:27:16 -05:00
"density": 1590,
2021-12-24 00:10:37 -05:00
},
2021-12-28 17:44:28 -05:00
"caramel": {
"color": "#e89a51",
"behavior": behaviors.LIQUID,
"reactions": {
"fire": { "elem1": "molasses" },
},
"viscosity": 500,
"temp": 40,
"tempLow": 24,
"stateLow": "candy",
"state": "liquid",
"density": 850,
},
"candy": {
"color": "#e6cab1",
"behavior": behaviors.WALL,
"tempHigh": 186,
"stateHigh": "caramel",
"density": 900,
},
"alcohol": {
"color": "#c9c5b1",
"behavior": behaviors.LIQUID,
"viscosity": 1,
"burn": 100,
"burnTime": 3,
"fireColor": ["#80ACF0","#96CDFE","#bee6d4"],
"category": "liquids",
"state": "liquid",
"density": 785.1,
},
"lichen": {
"color": ["#b6d6c3","#769482"],
"behavior": [
"XX|ST:wood|XX",
"ST:wood|XX|ST:wood",
"XX|M1|XX",
],
"tempHigh": 400,
"stateHigh": "fire",
"burn": 50,
"burnTime": 20,
"category": "life",
"state": "solid",
"density": 1.5,
},
2021-12-29 20:57:33 -05:00
"basalt": {
"color": "#2b2b2b",
"behavior": behaviors.STURDYPOWDER,
"tempHigh": 1262.5,
"stateHigh": "magma",
"category": "land",
"state": "solid",
"density": 3000,
},
"soap": {
"color": "#f2f2f2",
"behavior": [
"XX|CR:bubble%0.25|XX",
"M2|XX|M2",
"M2|M1|M2",
],
"reactions": {
"rust": { "elem2": "iron" },
"oxidized_copper": { "elem2": "copper" },
"blood": { "elem2": "water" },
"oxygen": { "elem2": "bubble" },
"plague": { "elem2": null },
"virus": { "elem2": null },
"mushroom_spore": { "elem2": null },
"lichen": { "elem2": null },
"rotten_meat": { "elem2": "meat" },
"acid_gas": { "elem2": "hydrogen" },
"carbon_dioxide": { "elem2": "oxygen" },
"acid": { "elem2": "hydrogen" },
"acid_cloud": { "elem2": "rain_cloud" },
},
"viscosity": 500,
"state": "liquid",
"category":"liquids",
"density": 1055,
},
"calcium": {
"color": ["#515053","#7a787d","#748193","#FEF9FF","#748193","#7a787d","#515053"],
"behavior": behaviors.POWDER,
"tempHigh": 842,
"state": "solid",
"density": 1550,
},
"limestone": {
"color": ["#C5B79C","#D9CCB2","#F8F1DB","#FCFAEB"],
"behavior": behaviors.STURDYPOWDER,
"tempHigh": 825,
"stateHigh": "quicklime",
"category": "land",
"state": "solid",
"density": 2100,
},
"quicklime": {
"color": "#E9EBE7",
"behavior": behaviors.POWDER,
"tempHigh": 4662,
"stateHigh": "molten_calcium",
"category": "land",
"state": "solid",
"density": 1025,
},
"slaked_lime": {
"color": "#adb8b5",
"behavior": behaviors.STURDYPOWDER,
"tempHigh": 580,
"stateHigh": "quicklime",
"category": "land",
"hidden": true,
"state": "solid",
"density": 2211,
},
"slug": {
"color": ["#997e12","#403314","#997e12","#403314","#997e12","#403314","#997e12","#403314","#997e12","#403314","#997e12","#403314","#124a44"],
"behavior": [
"XX|XX|XX",
"M2%0.5|XX|M2%0.5",
"XX|M1|XX",
],
"reactions": {
"salt": { "elem1": "slime", "elem2": null },
},
"tempLow": 5,
"stateLow": "slime",
"tempHigh": 40,
"stateHigh": "slime",
"category": "life",
"state": "solid",
"density": 1450,
},
"snail": {
"color": "#5c3104",
"behavior": [
"XX|XX|XX",
"M2%0.5|XX|M2%0.5",
"XX|M1|XX",
],
"reactions": {
"salt": { "elem1": "calcium", "elem2": null },
},
"tempLow": -6.4,
"stateLow": "calcium",
"tempHigh": 100,
"stateHigh": "calcium",
"category": "life",
"state": "solid",
"density": 1500,
},
2021-12-28 17:44:28 -05:00
2021-12-25 21:02:02 -05:00
2021-12-23 00:21:51 -05:00
}
// 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;
}
}
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;
}
// convert every color in the elements object to rgb
for (var key in elements) {
if (elements.hasOwnProperty(key)) {
2021-12-28 17:44:28 -05:00
// if the element has no color, skip it
if (elements[key].color === undefined) {
continue;
}
2021-12-23 00:21:51 -05:00
// 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;
}
}
}
}
2021-12-28 17:44:28 -05:00
// Automatic molten element generation
// 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 & & !elements[element].stateHigh) {
var newname = "molten_"+element;
elements[element].stateHigh = newname;
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];
r = c.r * 2;
g = c.g * 1.25;
b = c.b * 0.5;
if (r > 255) {r = 255;}
if (g > 255) {g = 255;}
colorList.push("rgb("+r+","+g+","+b+")");
colorObjectList.push({r:r,g:g,b:b});
r = c.r * 2;
g = c.g;
b = c.b * 0.5;
if (r > 255) {r = 255;}
if (g > 255) {g = 255;}
colorList.push("rgb("+r+","+g+","+b+")");
colorObjectList.push({r:r,g:g,b:b});
r = c.r * 2;
g = c.g * 0.75;
b = 0;
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 newmolten = {
//"name": newname.replaceAll("_"," "),
"color": colorList,
"colorObject": colorObjectList,
"behavior": behaviors.MOLTEN,
"temp": elements[element].tempHigh,
"tempLow": elements[element].tempHigh-100,
"stateLow": element,
"viscosity": elements[element].viscosity || 10000,
"hidden": true,
"state": "liquid",
}
// if the element has a density, add it to the new molten element * 0.9
if (elements[element].density) {
newmolten.density = elements[element].density * 0.9;
}
// if the new element doesn't exist, add it
if (!elements[newname]) {
elements[newname] = newmolten;
}
else {
// loop through newmolten's keys and values, copy them to the new element if they are not already defined
for (var key in newmolten) {
if (elements[newname][key] == undefined) {
elements[newname][key] = newmolten[key];
}
}
}
}
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;
}
}
2021-12-23 00:21:51 -05:00
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;
this.element = element;
var elementInfo = elements[element];
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;
if (elementInfo.burning) {
this.burning = true;
this.burnStart = pixelTicks;
}
else {
this.burning = false;
}
currentID++;
pixelMap[x][y] = this;
}
}
2021-12-28 17:44:28 -05:00
pixelSize = 9;
2021-12-23 00:21:51 -05:00
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) {
if (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) {
// if the pixel isn't in currentPixels, return
if (!currentPixels.includes(pixel)) {
return;
}
// 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) {
currentPixels.push(new Pixel(x, y, element));
}
function deletePixel(x,y,id=null) {
delete pixelMap[x][y];
if (id != null) {
for (var i = 0; i < currentPixels.length ; i + + ) {
if (currentPixels[i].id == id) {
currentPixels.splice(i, 1);
return;
}
}
}
for (var i = 0; i < currentPixels.length ; i + + ) {
if (currentPixels[i].x == x & & currentPixels[i].y == y) {
currentPixels.splice(i, 1);
break;
}
}
}
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;
}
2021-12-28 17:44:28 -05:00
function reactPixels(pixel1,pixel2) {
var elem1 = pixel1.element;
if (elements[elem1].reactions[pixel2.element].elem1 !== undefined) {
if (elements[elem1].reactions[pixel2.element].elem1 == null) {
deletePixel(pixel1.x,pixel1.y);
}
else {
pixel1.element = elements[elem1].reactions[pixel2.element].elem1;
pixel1.color = pixelColorPick(pixel1);
pixel1.start = pixelTicks;
if (elements[elem1].burning != true) {
pixel1.burning = false;
}
}
}
if (elements[elem1].reactions[pixel2.element].elem2 !== undefined) {
if (elements[elem1].reactions[pixel2.element].elem2 == null) {
deletePixel(pixel2.x,pixel2.y);
}
else {
pixel2.element = elements[elem1].reactions[pixel2.element].elem2;
pixel2.color = pixelColorPick(pixel2);
pixel2.start = pixelTicks;
if (elements[pixel2.element].burning != true) {
pixel2.burning = false;
}
}
}
}
validDensitySwaps = ["solid>liquid","liquid>gas","liquid>liquid","gas>gas","solid>gas"];
function tryMove(pixel,nx,ny,leaveBehind=undefined) {
var info = elements[pixel.element];
if (isEmpty(nx,ny)) { // If coords is empty, move to coords
movePixel(pixel,nx,ny,leaveBehind);
return true;
}
else {
if (!outOfBounds(nx,ny)) {
// Reactions
newPixel = pixelMap[nx][ny];
if (info.reactions != undefined) {
if (info.reactions[newPixel.element] != undefined) {
reactPixels(pixel,newPixel);
return true;
}
}
else if (elements[newPixel.element].reactions != undefined) {
if (elements[newPixel.element].reactions[pixel.element] != undefined) {
reactPixels(newPixel,pixel);
return true;
}
}
// Density
if (pixel.element != newPixel.element) {
if (elements[newPixel.element].density != undefined & & info.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
2021-12-28 21:27:54 -05:00
if (validDensitySwaps.includes(info.state+">"+elements[newPixel.element].state) & & info.density >= elements[newPixel.element].density) {
2021-12-28 17:44:28 -05:00
// 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;
}
}
}
}
}
}
return false;
}
2021-12-23 00:21:51 -05:00
function behaviorCoords(x,y,bx,by) {
2021-12-30 13:27:16 -05:00
return {x:x+bx-1,y:y+by-1};
2021-12-23 00:21:51 -05:00
}
2021-12-28 17:44:28 -05:00
/* Behavior Example (Sand)
2021-12-23 00:21:51 -05:00
[
["XX","XX","XX"],
["XX","XX","XX"],
["M2","M1","M2"]
] */
2021-12-30 13:27:16 -05:00
function rotateBehavior(behavior,rotation) {
// returns rotated 2D array counter-clockwise depending on rotation 1, 2, or 3
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;
}
return newBehavior;
}
function flipBehavior(behavior,axis) {
// returns flipped 2D array depending on axis "x" or "y"
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];
}}
return newBehavior;
}
else if (axis === "y") {
return behavior.slice().reverse();
}
return behavior;
}
2021-12-23 00:21:51 -05:00
/* Behavior Rules
XX = Ignore
M1 = Move (First Priority)
M2 = Move (Second Priority)
SP = Support (Doesn't move if all aren't empty)
DL = Delete
CL = Clone
CH = Change
RP = Replace (Move to an existing element)
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)
%(num) = Chance of rule happening
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
*/
function pixelTick(pixel) {
if (pixel.start == pixelTicks) {return}
var info = elements[pixel.element];
var behavior = info.behavior;
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;
// Parse behavior
for (var by = 0; by < behavior.length ; by + + ) {
for (var bx = 0; bx < behavior [ by ] . length ; bx + + ) {
var b0 = behavior[by][bx].trim();
2021-12-28 17:44:28 -05:00
if (b0 == "XX") {continue}
2021-12-23 00:21:51 -05:00
//if (b.includes(" OR ")) {
// b = b.split(" OR ")[Math.floor(Math.random()*b.split(" OR ").length)];
//}
// Loop through b0.split(" AND ")
for (var i = 0; i < b0.split ( " AND " ) . length ; i + + ) {
var b = b0.split(" AND ")[i];
var arg = null;
if (b.includes(":")) {
arg = b.split(":")[1].split(/[\:\%]/)[0];
if (!b.includes("%")) {
b = b.split(/[\:\%]/)[0];
}
}
// If b has "%" followed by a number in it, it's a chance to move
if (b.includes("%")) {
// 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; }
2021-12-28 17:44:28 -05:00
if (chance==100 || Math.random()*100 < chance ) {
2021-12-23 00:21:51 -05:00
var newCoords = behaviorCoords(x,y,bx,by);
if (b == "M1") {
2021-12-28 17:44:28 -05:00
if (info.viscosity != undefined) {
if (!((Math.random()*100) < 100 / ( ( info . viscosity ) * * 0 . 25 ) ) ) {
newCoords.x = x;
}
2021-12-23 00:21:51 -05:00
}
move1Spots.push(newCoords);
}
else if (b == "M2") {
2021-12-28 17:44:28 -05:00
if (info.viscosity != undefined) {
if (!((Math.random()*100) < 100 / ( ( info . viscosity ) * * 0 . 25 ) ) ) {
newCoords.x = x;
}
2021-12-23 00:21:51 -05:00
}
move2Spots.push(newCoords);
}
else if (b == "SP") {
supportSpots.push({x:newCoords.x,y:newCoords.y,arg:arg});
}
else if (b == "DL") {
if ((!isEmpty(newCoords.x,newCoords.y)) & & !outOfBounds(newCoords.x,newCoords.y)) {
// if the pixel at newCoords is the same element as the pixel, ignore
newPixel = pixelMap[newCoords.x][newCoords.y];
if ((!(newPixel.element == pixel.element)) || (newCoords.x == x & & newCoords.y == y)) {
if (arg != null) { var args = arg.split(","); }
if (arg == null || args.includes(newPixel.element)) {
deletePixel(newCoords.x,newCoords.y);
if (newCoords.x == x & & newCoords.y == y) {
2021-12-28 17:44:28 -05:00
var deleted = true;
2021-12-23 00:21:51 -05:00
}
2021-12-28 17:44:28 -05:00
swapSpots = [];
2021-12-23 00:21:51 -05:00
}
}
}
}
2021-12-29 20:57:33 -05:00
// Clone self
2021-12-23 00:21:51 -05:00
else if (b == "CL") {
if (isEmpty(newCoords.x,newCoords.y)) {
2021-12-28 17:44:28 -05:00
if (arg == null || pixel.temp >= parseFloat(arg)) {
clonePixel(pixel,newCoords.x,newCoords.y);
}
2021-12-23 00:21:51 -05:00
}
}
2021-12-29 20:57:33 -05:00
// Clone first touched
else if (b == "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;
}
}
else {
if (!isEmpty(newCoords.x,newCoords.y) & & !outOfBounds(newCoords.x,newCoords.y)) {
newPixel = pixelMap[newCoords.x][newCoords.y];
if (newPixel.element != pixel.element) {
pixel.clone = newPixel.element;
}
else if (newPixel.clone) {
pixel.clone = newPixel.clone;
}
}
}
}
2021-12-23 00:21:51 -05:00
//Change pixel
else if (b == "CH") {
if (!isEmpty(newCoords.x,newCoords.y) & & !outOfBounds(newCoords.x,newCoords.y)) {
var newPixel = pixelMap[newCoords.x][newCoords.y];
if (arg.includes(">")) {
var argfrom = arg.split(">")[0];
var argto = arg.split(">")[1];
}
else {
var argfrom = null;
var argto = arg;
}
if (argto.includes(",")) {
var argto = argto.split(",")[Math.floor(Math.random()*argto.split(",").length)];
}
if ((newPixel.element != argto) & & (argfrom == null || argfrom == newPixel.element)) {
newPixel.element = argto;
newPixel.color = pixelColorPick(newPixel);
newPixel.start = pixelTicks;
if (elements[argto].burning != true) {
newPixel.burning = false;
}
}
}
}
//Replace pixel
/*else if (b == "RP") {
replaceSpots.push({x:newCoords.x,y:newCoords.y,arg:arg});
}*/
//Create pixel
else if (b == "CR") {
if (isEmpty(newCoords.x,newCoords.y)) {
if (arg == null) {
arg = pixel.element;
}
else if (arg.includes(",")) {
arg = arg.split(",")[Math.floor(Math.random()*arg.split(",").length)];
}
createPixel(arg,newCoords.x,newCoords.y);
2021-12-23 23:42:03 -05:00
pixelMap[newCoords.x][newCoords.y].temp = pixel.temp
2021-12-23 00:21:51 -05:00
}
}
//Leave behind element
else if (b == "LB" || b == "L1" || b == "L2") {
if (arg != null & & arg.includes(",")) {
arg = arg.split(",")[Math.floor(Math.random()*arg.split(",").length)];
}
if (b=="LB") {leaveBehind = arg;}
else if (b=="L1") {leaveBehind1 = arg;}
else if (b=="L2") {leaveBehind2 = arg;}
}
//Swap
else if (b == "SW") {
if (!isEmpty(newCoords.x,newCoords.y) & & !outOfBounds(newCoords.x,newCoords.y)) {
var newPixel = pixelMap[newCoords.x][newCoords.y];
if (arg != null) { var args = arg.split(","); }
if (arg == null || args.includes(newPixel.element)) {
swapSpots.push({x:newCoords.x,y:newCoords.y});
}
}
}
//Heat
else if (b == "HT") {
if (!isEmpty(newCoords.x,newCoords.y) & & !outOfBounds(newCoords.x,newCoords.y)) {
var newPixel = pixelMap[newCoords.x][newCoords.y];
2021-12-24 00:10:37 -05:00
if (!(newPixel.element == pixel.element)) {
if (arg != null) {arg = parseFloat(arg)}
else {arg = 1}
2021-12-31 01:04:30 -05:00
if (isNaN(arg)) {arg = 1}
2021-12-24 00:10:37 -05:00
newPixel.temp += arg;
pixelTempCheck(newPixel);
}
2021-12-23 00:21:51 -05:00
}
}
//Cool
else if (b == "CO") {
if (!isEmpty(newCoords.x,newCoords.y) & & !outOfBounds(newCoords.x,newCoords.y)) {
var newPixel = pixelMap[newCoords.x][newCoords.y];
2021-12-24 00:10:37 -05:00
if (!(newPixel.element == pixel.element)) {
if (arg != null) {arg = parseFloat(arg)}
else {arg = 1}
2021-12-31 01:04:30 -05:00
if (isNaN(arg)) {arg = 1}
2021-12-24 00:10:37 -05:00
newPixel.temp -= arg;
pixelTempCheck(newPixel);
}
2021-12-23 00:21:51 -05:00
}
}
//Change color
else if (b == "CC") {
if (!isEmpty(newCoords.x,newCoords.y) & & !outOfBounds(newCoords.x,newCoords.y)) {
var newPixel = pixelMap[newCoords.x][newCoords.y];
if (arg == null) {arg = newPixel.colorObject}
else {
if (arg.includes(",")) {
arg = arg.split(",")[Math.floor(Math.random()*arg.split(",").length)];
}
if (!arg.startsWith("#")) {
arg = "#" + arg;
}
}
newPixel.color = pixelColorPick(newPixel,arg);
}
}
//Stick
else if (b=="ST") {
if (!isEmpty(newCoords.x,newCoords.y) & & !outOfBounds(newCoords.x,newCoords.y)) {
var newPixel = pixelMap[newCoords.x][newCoords.y];
if (newPixel.element != pixel.element & & (arg == null || newPixel.element == arg)) {
2021-12-28 17:44:28 -05:00
var sticking = true
2021-12-23 00:21:51 -05:00
}
}
}
}
}
}
}
2021-12-28 17:44:28 -05:00
if (typeof deleted !== "undefined") {return;}
2021-12-23 00:21:51 -05:00
var move = true;
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)) & & !outOfBounds(bx,by)) {
if (pixelMap[bx][by].element == arg || arg == null) {
supportCount++;
}
}
}
if (supportCount == supportSpots.length) {
move = false;
}
}
/*replaceSpotsCopy = replaceSpots.slice();
if (replaceSpots.length > 0) {
2021-12-28 17:44:28 -05:00
while (replaceSpots.length > 0) {
2021-12-23 00:21:51 -05:00
// coords = random item of replaceSpots
var newCoords = replaceSpots[Math.floor(Math.random()*replaceSpots.length)];
if (!isEmpty(newCoords.x,newCoords.y) & & !outOfBounds(newCoords.x,newCoords.y)) {
if (newPixel.element == newCoords.arg || newCoords.arg == null) {
var newPixel = pixelMap[newCoords.x][newCoords.y];
var newCoords = replaceSpots[Math.floor(Math.random()*replaceSpots.length)];
deletePixel(newCoords.x,newCoords.y);
pixelMap[newCoords.x][newCoords.y] = pixel;
pixel.x = newCoords.x;
pixel.y = newCoords.y;
moved = true;
replaceSpotsCopy.splice(replaceSpotsCopy.indexOf(newCoords),1);
break;
}
}
replaceSpots.splice(replaceSpots.indexOf(newCoords),1);
}
}
if (replaceSpotsCopy.length > 0 & & !moved) {
// combine replaceSpotsCopy and move2Spots
move2Spots = move2Spots.concat(replaceSpotsCopy);
}*/
var moved = false;
if (swapSpots.length > 0) {
var coords = swapSpots[Math.floor(Math.random()*swapSpots.length)];
2021-12-28 17:44:28 -05:00
if (pixelMap[coords.x][coords.y] != undefined) {
swapPixels(pixel,pixelMap[coords.x][coords.y]);
move = false;
moved = true;
}
2021-12-23 00:21:51 -05:00
}
2021-12-28 17:44:28 -05:00
if (typeof sticking !== "undefined") {
2021-12-23 00:21:51 -05:00
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;
2021-12-28 17:44:28 -05:00
moved = tryMove(pixel,nx,ny,leaveBehind1 || leaveBehind);
if (moved) {
2021-12-23 00:21:51 -05:00
break;
}
2021-12-28 17:44:28 -05:00
else {
// remove coords from move1Spots
2021-12-23 00:21:51 -05:00
move1Spots.splice(move1Spots.indexOf(coords),1);
}
2021-12-28 17:44:28 -05:00
2021-12-23 00:21:51 -05:00
}
}
// 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;
2021-12-28 19:02:21 -05:00
moved = tryMove(pixel,nx,ny,leaveBehind2 || leaveBehind);
2021-12-28 17:44:28 -05:00
if (moved) {
2021-12-23 00:21:51 -05:00
break;
}
2021-12-28 17:44:28 -05:00
else {
// remove coords from move2Spots
2021-12-23 00:21:51 -05:00
move2Spots.splice(move2Spots.indexOf(coords),1);
}
}
}
}
if (pixel.burning) {
pixel.temp += 1;
pixelTempCheck(pixel);
var burnSpots = [
{x:pixel.x+1,y:pixel.y},
{x:pixel.x-1,y:pixel.y},
{x:pixel.x,y:pixel.y+1},
{x:pixel.x,y:pixel.y-1},
];
// loop through burnspots
for (var i = 0; i < burnSpots.length ; i + + ) {
var burnSpot = burnSpots[i];
if (!isEmpty(burnSpot.x,burnSpot.y) & & !outOfBounds(burnSpot.x,burnSpot.y)) {
var newPixel = pixelMap[burnSpot.x][burnSpot.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 ((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)];
}
pixel.element = burnInto;
if (info.fireColor != undefined & & burnInto == "fire") {
pixel.color = pixelColorPick(pixel,info.fireColor);
}
else {
pixel.color = pixelColorPick(pixel)
}
pixel.start = pixelTicks;
if (elements[burnInto].burning != true) {
pixel.burning = false;
delete pixel.burnStart;
}
else {
pixel.burning = true;
pixel.burnStart = pixelTicks;
}
if (elements[burnInto].temp != undefined) {
pixel.temp = elements[burnInto].temp;
pixelTempCheck(pixel)
}
}
else if (pixel.element != "fire" & & isEmpty(pixel.x,pixel.y-1) & & Math.floor(Math.random()*100)< 10 ) {
createPixel("fire",pixel.x,pixel.y-1);
2021-12-23 23:42:03 -05:00
pixelMap[pixel.x][pixel.y-1].temp = pixel.temp//+(pixelTicks - (pixel.burnStart || 0));
2021-12-23 00:21:51 -05:00
if (info.fireColor != undefined) {
pixelMap[pixel.x][pixel.y-1].color = pixelColorPick(pixelMap[pixel.x][pixel.y-1],info.fireColor);
}
}
}
2021-12-28 17:44:28 -05:00
// Change tempearture if needed (unused)
/*if (info.tempChange != undefined) {
2021-12-23 00:21:51 -05:00
pixel.temp += info.tempChange;
pixelTempCheck(pixel);
2021-12-28 17:44:28 -05:00
}*/
2021-12-23 00:21:51 -05:00
2021-12-23 23:42:03 -05:00
// Heat Transfer
2021-12-24 00:10:37 -05:00
if (!(info.insulate == true)) {
// Check right and bottom adjacent pixels
coordsToCheck = [
{x:pixel.x+1,y:pixel.y},
{x:pixel.x,y:pixel.y+1},
];
for (var i = 0; i < coordsToCheck.length ; i + + ) {
var coords = coordsToCheck[i];
if (!isEmpty(coords.x,coords.y) & & !outOfBounds(coords.x,coords.y)) {
var newPixel = pixelMap[coords.x][coords.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);
2021-12-23 23:42:03 -05:00
}
}
}
2021-12-23 00:21:51 -05:00
}
function pixelColorPick(pixel,customColor=null) {
var element = pixel.element;
var elementInfo = elements[element];
//if (elementInfo.behavior instanceof Array) {
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) {
var elementInfo = elements[pixel.element];
2021-12-28 17:44:28 -05:00
if (pixel.temp < -273.15 ) { / / Absolute Zero
pixel.temp = -273.15;
}
2021-12-23 00:21:51 -05:00
// If the pixel's temp >= the elementInfo tempHigh, change pixel.element to elementInfo.stateHigh
if (pixel.temp >= elementInfo.tempHigh) {
pixel.element = elementInfo.stateHigh;
pixel.color = pixelColorPick(pixel);
if (pixel.burning) {
pixel.burning = false;
delete pixel.burnStart;
}
if (elements[elementInfo.stateHigh].burning == true) {
pixel.burning = true;
pixel.burnStart = pixelTicks;
}
}
// If the pixel's temp < = the elementInfo tempLow, change pixel.element to elementInfo.stateLow
else if (pixel.temp < = elementInfo.tempLow) {
pixel.element = elementInfo.stateLow;
pixel.color = pixelColorPick(pixel);
if (pixel.burning) {
pixel.burning = false;
delete pixel.burnStart;
}
if (elements[elementInfo.stateLow].burning) {
pixel.burning = true;
pixel.burnStart = pixelTicks;
}
}
}
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;
}
hiding = false;
function drawPixels(forceTick=false) {
// newCurrentPixels = shuffled currentPixels
var newCurrentPixels = currentPixels.slice();
newCurrentPixels.sort(function() {return 0.5 - Math.random()});
for (var i = 0; i < newCurrentPixels.length ; i + + ) {
pixel = newCurrentPixels[i];
2021-12-28 17:44:28 -05:00
if (pixelMap[pixel.x][pixel.y] == undefined || currentPixels.indexOf(pixel) == -1) {continue}
2021-12-23 00:21:51 -05:00
if ((!paused) || forceTick) {pixelTick(pixel);};
}
2021-12-28 17:44:28 -05:00
// Draw the current pixels
if (!hiding) {
var canvas = document.getElementById("game");
var ctx = canvas.getContext("2d");
for (var i = 0; i < newCurrentPixels.length ; i + + ) {
pixel = newCurrentPixels[i];
if (pixelMap[pixel.x][pixel.y] == undefined) {continue}
2021-12-23 00:21:51 -05:00
ctx.fillStyle = pixel.color;
ctx.fillRect(pixel.x*pixelSize, pixel.y*pixelSize, pixelSize, pixelSize);
}
}
if ((!paused) || forceTick) {pixelTicks++};
}
function tick() {
// If mouseIsDown, do mouseAction
if (mouseIsDown) {
mouseAction(null,mousePos.x,mousePos.y);
}
// Get the canvas
var canvas = document.getElementById("game");
var ctx = canvas.getContext("2d");
// Clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawPixels();
2021-12-28 17:44:28 -05:00
if (currentElement == "pick" || currentElement == "lookup") {
2021-12-23 00:21:51 -05:00
var mouseOffset = 0;
}
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 rectangle 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);
updateStats();
ticks ++;
}
currentElement = "sand";
mouseIsDown = false;
mouseType = null;
function mouseClick(e) {
mouseIsDown = true;
// If it's a left click
if (e.button == 0) {
mouseType = "left";
}
else if (e.button == 2) {
mouseType = "right";
}
// middle click
else if (e.button == 1) {
mouseType = "middle";
}
mouseMove(e);
}
function mouseUp(e) {
mouseIsDown = false;
}
function getMousePos(canvas, evt) {
// If evt.touches is defined, use the first touch
if (evt.touches) {
evt.preventDefault();
evt = evt.touches[0];
}
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) {
mouseAction(e);
}
else {
var canvas = document.getElementById("game");
mousePos = getMousePos(canvas, e);
}
}
function mouseAction(e,mouseX=undefined,mouseY=undefined) {
2021-12-29 20:57:33 -05:00
if (showingInfo & & currentElement != "lookup") {
2021-12-28 17:44:28 -05:00
closeInfo();
}
2021-12-23 00:21:51 -05:00
if (mouseType == "left") { mouse1Action(e,mouseX,mouseY); }
else if (mouseType == "right") { mouse2Action(e,mouseX,mouseY); }
else if (mouseType == "middle") { mouseMiddleAction(e,mouseX,mouseY); }
}
mouseSize = 5;
mousePos = {x:0,y:0};
function mouseRange(mouseX,mouseY) {
var coords = [];
var mouseOffset = Math.trunc(mouseSize/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) {
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");
mousePos = getMousePos(canvas, e);
var mouseX = mousePos.x;
var mouseY = mousePos.y;
}
2021-12-28 17:44:28 -05:00
if (currentElement == "lookup") {
if (!isEmpty(mouseX,mouseY) & & !outOfBounds(mouseX,mouseY)) {
showInfo(pixelMap[mouseX][mouseY].element);
}
return;
}
2021-12-23 00:21:51 -05:00
var coords = mouseRange(mouseX,mouseY);
var element = elements[currentElement];
2021-12-28 17:44:28 -05:00
var mixList = [];
2021-12-23 00:21:51 -05:00
// 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 element name is heat or cool
if (currentElement == "heat" || currentElement == "cool") {
if (!isEmpty(x,y,false)) {
if (outOfBounds(x,y)) {
continue;
}
var pixel = pixelMap[x][y];
2021-12-24 00:10:37 -05:00
if (shiftDown) {pixel.temp += element.temp+(Math.random()*element.temp*1.5)*20;}
else {pixel.temp += element.temp+(Math.random()*element.temp*1.5);}
2021-12-23 00:21:51 -05:00
pixelTempCheck(pixel);
}
}
2021-12-28 17:44:28 -05:00
else if (currentElement == "mix") {
if (!isEmpty(x,y) & & !outOfBounds(x,y)) {
var pixel = pixelMap[x][y];
if (pixel.element != "fire") {
mixList.push(pixel);
}
}
}
2021-12-23 00:21:51 -05:00
else if (placeMode == "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);
}
currentPixels.push(new Pixel(x, y, currentElement));
}
else if (isEmpty(x, y)) {
currentPixels.push(new Pixel(x, y, currentElement));
}
}
2021-12-28 17:44:28 -05:00
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);
}
}
2021-12-23 00:21:51 -05:00
}
function mouse2Action(e,mouseX=undefined,mouseY=undefined) {
// Erase pixel at mouse position
if (mouseX == undefined & & mouseY == undefined) {
var canvas = document.getElementById("game");
var ctx = canvas.getContext("2d");
mousePos = getMousePos(canvas, e);
var mouseX = mousePos.x;
var mouseY = mousePos.y;
}
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) {
// Erase pixel at mouse position
if (mouseX == undefined & & mouseY == undefined) {
var canvas = document.getElementById("game");
var ctx = canvas.getContext("2d");
mousePos = getMousePos(canvas, e);
var mouseX = mousePos.x;
var mouseY = mousePos.y;
}
if (!isEmpty(mouseX, mouseY) & & !outOfBounds(mouseX, mouseY)) {
selectElement(pixelMap[mouseX][mouseY].element);
mouseIsDown = false;
}
}
2021-12-28 17:44:28 -05:00
function wheelHandle(e) {
e.preventDefault();
var deltaY = e.deltaY*0.1;
if (Math.round(deltaY) == 0) {
if (deltaY > 0) { deltaY = 1; }
else { deltaY = -1; }
}
mouseSize += Math.round(deltaY*2);
if (mouseSize < 1 ) { mouseSize = 1; }
if (mouseSize > (height > width ? height : width)) { mouseSize = (height > width ? height : width); }
}
2021-12-23 00:21:51 -05:00
function chooseElementPrompt() {
2021-12-28 17:44:28 -05:00
var e = prompt("Enter the element's ID")
2021-12-23 00:21:51 -05:00
if (elements[e] != undefined) {
2021-12-28 17:44:28 -05:00
e = e.replace(/ /g,"_");
2021-12-23 00:21:51 -05:00
selectElement(e);
var btn = document.getElementById("elementButton-"+e);
if (btn != null) {
btn.setAttribute("current","true");
}
};
}
function togglePause() {
paused = !paused;
if (paused) {
document.getElementById("pauseButton").setAttribute("on","true");
}
else {
document.getElementById("pauseButton").setAttribute("on","false");
}
}
function doFrame() {
if (!paused) {
paused=true;
document.getElementById("pauseButton").setAttribute("on","true");
}
drawPixels(true);
}
function selectElement(element) {
var e1 = document.getElementById("elementButton-"+currentElement)
if (e1 != null) { e1.setAttribute("current","false"); }
currentElement = element;
var e2 = document.getElementById("elementButton-"+element)
if (e2 != null) { e2.setAttribute("current","true"); }
}
function clearAll() {
currentPixels = [];
pixelMap = [];
for (var i = 0; i < width ; i + + ) {
pixelMap[i] = [];
for (var j = 0; j < height ; j + + ) {
pixelMap[i][j] = undefined;
}
}
pixelTicks = 0;
}
// Update stats
function updateStats() {
var statsDiv = document.getElementById("stats");
statsDiv.innerHTML = "< span id = 'stat-pos' class = 'stat' > x"+mousePos.x+",y"+mousePos.y+"< / span > ";
statsDiv.innerHTML += "< span id = 'stat-pixels' class = 'stat' > Pxls:" + currentPixels.length+"< / span > ";
statsDiv.innerHTML += "< span id = 'stat-tps' class = 'stat' > " + tps+"tps< / span > ";
statsDiv.innerHTML += "< span id = 'stat-ticks' class = 'stat' > " + pixelTicks+"< / span > ";
if (typeof pixelMap == 'undefined') { return; }
if (pixelMap[mousePos.x] != undefined) {
var currentPixel = pixelMap[mousePos.x][mousePos.y];
if (currentPixel != undefined) {
statsDiv.innerHTML += "< span id = 'stat-element' class = 'stat' > Elem:"+currentPixel.element.toUpperCase()+"< / span > ";
statsDiv.innerHTML += "< span id = 'stat-temperature' class = 'stat' > Temp:"+Math.round(currentPixel.temp)+"°C< / span > ";
if (currentPixel.burning) {
statsDiv.innerHTML += "< span id = 'stat-burning' class = 'stat' > Burning< / span > ";
}
}
}
if (shiftDown) {
2021-12-28 17:44:28 -05:00
if (shiftDown==1) {statsDiv.innerHTML += "< span id = 'stat-shift' class = 'stat' > [↑ ]< / span > ";}
else if (shiftDown==2) {statsDiv.innerHTML += "< span id = 'stat-shift' class = 'stat' > [A ]< / span > ";}
else if (shiftDown==3) {statsDiv.innerHTML += "< span id = 'stat-shift' class = 'stat' > [ ↑]< / span > ";}
else if (shiftDown==4) {statsDiv.innerHTML += "< span id = 'stat-shift' class = 'stat' > [ A]< / span > ";}
2021-12-23 00:21:51 -05:00
}
}
2021-12-28 17:44:28 -05:00
showingInfo = false;
function infoLink(l) {
if (l instanceof Array) {
var newtext = "";
for (var i = 0; i < l.length ; i + + ) {
var element = l[i];
// add to newtext a span with the element's name and its onclick to showInfo(element)
if (l=="pixels") { newtext += "pixels, "}
else { newtext += "< span class = 'infoLink' onclick = 'showInfo(\""+element+"\")' > "+element.toUpperCase().replace(/_/g," ")+"< / span > , ";}
}
// remove the last comma and space
newtext = newtext.substring(0, newtext.length-2);
return newtext
}
else {
if (l=="pixels" || l=="[???]") {return "pixels"}
else {return "< span class = 'infoLink' onclick = 'showInfo(\""+l+"\")' > "+l.toUpperCase().replace(/_/g," ")+"< / span > ";}
}
}
function showInfo(element) { // this is such a mess please don't look at it
showingInfo = true;
var infoScreen = document.getElementById("infoScreen");
infoScreen.style.display = "block";
var infoSearch = document.getElementById("infoSearch");
infoSearch.focus();
var infoTitle = document.getElementById("infoTitle");
var infoText = document.getElementById("infoText");
if (element != undefined) {
// replace all spaces with underscores
element = element.replace(/ /g,"_");
infoSearch.value = element;
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 = "";
infoSearch.style.backgroundColor = "rgb(66, 66, 66)";
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 > ";
}
}
var moves = false;
var deletes = [];
var swaps = [];
var creates = [];
var heats = false;
var cools = false;
var clones = 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 (!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(",")); }
}
}}}}
2021-12-28 19:02:21 -05:00
// 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;});
2021-12-28 17:44:28 -05:00
if (info.category == "tools") { infoText.innerHTML += "\nTool."}
else {
if (!moves) { infoText.innerHTML += "\nStationary."; }
if (info.category) { infoText.innerHTML += "\nCategory: "+info.category.toUpperCase()+"."; }
}
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 (info.hidden) { infoText.innerHTML += "\nHidden from toolbar."; }
if (info.density != undefined) { infoText.innerHTML += "\nDensity: "+info.density+"kg⁄ m< sup > 3< / sup > ."; }
if (info.tempHigh != undefined) {
2021-12-28 21:27:54 -05:00
infoText.innerHTML += "\nTurns into "+infoLink(info.stateHigh || "[???]")+" above "+info.tempHigh+"°C.";
2021-12-28 17:44:28 -05:00
}
if (info.tempLow != undefined) {
2021-12-28 21:27:54 -05:00
infoText.innerHTML += "\nTurns into "+infoLink(info.stateLow || "[???]")+" below "+info.tempLow+"°C.";
2021-12-28 17:44:28 -05:00
}
if (info.burn != undefined) { infoText.innerHTML += "\nFlammability: "+info.burn+"%."; }
2021-12-28 19:02:21 -05:00
if (info.burnTime != undefined) {
infoText.innerHTML += "\nBurns for "+info.burnTime+" tick";
if (info.burnTime != 1) { infoText.innerHTML += "s"; }
infoText.innerHTML += ".";
}
2021-12-28 17:44:28 -05:00
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.reactions) {
infoText.innerHTML += "\nReacts with " + infoLink(Object.keys(info.reactions)) + ".";
}
}
else {
infoTitle.innerHTML = "";
infoText.innerHTML = "";
// infoSearch red background
infoSearch.style.backgroundColor = "rgb(100, 33, 33)";
}
}
else {
infoTitle.innerHTML = "";
infoText.innerHTML = "";
infoSearch.style.backgroundColor = "rgb(66, 66, 66)";
}
}
function closeInfo() {
var infoScreen = document.getElementById("infoScreen");
var infoSearch = document.getElementById("infoSearch");
infoScreen.style.display = "none";
infoSearch.value = "";
infoSearch.blur();
showingInfo = false;
}
2021-12-23 00:21:51 -05:00
// 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);
}
ticks = 0;
pixelTicks = 0;
placeMode = null;
paused = false;
2021-12-28 17:44:28 -05:00
function focusGame() { document.getElementById("game").focus(); if(showingInfo) { closeInfo(); } }
2021-12-23 00:21:51 -05:00
//on window load
window.onload = function() {
// While the mouse is down, run mouseDown()
var gameCanvas = document.getElementById("game");
// Get context
var ctx = gameCanvas.getContext("2d");
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 800, set it to 800
if (newWidth > 1000) { newWidth = 1000; }
// If we are on a desktop and the new height is greater than 600, set it to 600
2021-12-28 17:44:28 -05:00
if (window.innerWidth > 1000 & & newHeight > 500) { newHeight = 500; }
2021-12-23 00:21:51 -05:00
ctx.canvas.width = newWidth;
ctx.canvas.height = newHeight;
width = Math.round(newWidth/pixelSize)-1;
height = Math.round(newHeight/pixelSize)-1;
// Object with width arrays of pixels starting at 0
pixelMap = {};
for (var i = 0; i < width ; i + + ) {
pixelMap[i] = [];
}
//...drawing code...
gameCanvas.addEventListener("mousedown", mouseClick);
gameCanvas.addEventListener("touchstart", mouseClick);
window.addEventListener("mouseup", mouseUp);
window.addEventListener("touchend", mouseUp);
window.addEventListener("mousemove", mouseMove);
gameCanvas.addEventListener("touchmove", mouseMove);
2021-12-28 17:44:28 -05:00
gameCanvas.addEventListener("wheel", wheelHandle);
2021-12-23 00:21:51 -05:00
gameCanvas.ontouchstart = function(e) {
if (e.touches) e = e.touches[0];
return false;
}
2021-12-28 17:44:28 -05:00
shiftDown = 0;
2021-12-23 00:21:51 -05:00
// If the user presses [ or -, decrease the mouse size by 2
document.addEventListener("keydown", function(e) {
2021-12-28 17:44:28 -05:00
if (showingInfo) {
// esc or / to close
if (e.keyCode == 27 || e.keyCode == 191) { closeInfo(); }
// enter to clear infoSearch
else if (e.keyCode == 13) {
var infoSearch = document.getElementById("infoSearch");
infoSearch.value = "";
showInfo();
}
return;
}
2021-12-23 00:21:51 -05:00
if (e.keyCode == 219 || e.keyCode == 189) {
if (shiftDown) {mouseSize = 1}
else {
mouseSize -= 2;
if (mouseSize < 1 ) { mouseSize = 1; }
}
}
// If the user presses ] 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); }
}
2021-12-28 17:44:28 -05:00
// User presses shift
else if (e.keyCode == 16) {
if (event.location === KeyboardEvent.DOM_KEY_LOCATION_LEFT) {
shiftDown = 1;
} else if (event.location === KeyboardEvent.DOM_KEY_LOCATION_RIGHT) {
shiftDown = 3;
}
}
// User presses alt
else if (e.keyCode == 18) {
if (event.location === KeyboardEvent.DOM_KEY_LOCATION_LEFT) {
shiftDown = 2;
} else if (event.location === KeyboardEvent.DOM_KEY_LOCATION_RIGHT) {
shiftDown = 4;
}
}
2021-12-23 00:21:51 -05:00
// 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();
}
// . = doFrame()
else if (e.keyCode == 190) {
e.preventDefault();
doFrame();
}
2021-12-28 17:44:28 -05:00
// / or i = showInfo()
else if (e.keyCode == 191 || e.keyCode == 73) {
e.preventDefault();
showInfo();
}
2021-12-23 00:21:51 -05:00
});
// If the user releases either shift
document.addEventListener("keyup", function(e) {
2021-12-28 17:44:28 -05:00
if (e.keyCode == 16 || e.keyCode == 18) { shiftDown = 0; }
2021-12-23 00:21:51 -05:00
});
// Create buttons for elements
// For each element type in elements, create a button in controls that sets the current element to that type
// Alphabetically sort and loop through dictionary named "elements"
elementCount = 0;
hiddenCount = 0;
for (var element in elements) {
elementCount++;
if (elements[element].hidden) { hiddenCount++; continue; }
var category = elements[element].category;
if (category==null) {category="Other"}
var categoryDiv = document.getElementById("category-"+category);
if (categoryDiv == null) {
2021-12-28 17:44:28 -05:00
categoryButton = document.createElement("button");
categoryButton.id = "categoryButton-"+category;
categoryButton.innerHTML = 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() {
var category = this.getAttribute("category");
var categoryDiv = document.getElementById("category-"+category);
// Show this categoryDiv and hide all others
for (var i = 0; i < this.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";
this.setAttribute("current", true);
}
document.getElementById("categoryControls").appendChild(categoryButton);
2021-12-23 00:21:51 -05:00
categoryDiv = document.createElement("div");
2021-12-28 17:44:28 -05:00
//categoryDiv.innerHTML = "< span class = 'categoryName' > "+category+"< / span > ";
2021-12-23 00:21:51 -05:00
categoryDiv.setAttribute("id","category-"+category);
2021-12-28 17:44:28 -05:00
categoryDiv.setAttribute("category",category);
2021-12-23 00:21:51 -05:00
categoryDiv.setAttribute("class","category");
document.getElementById("elementControls").appendChild(categoryDiv);
}
var button = document.createElement("button");
2021-12-28 17:44:28 -05:00
// if the element has the attribute "name", use that as the button's text, otherwise use the element with underscores replaced by spaces
if (elements[element].name) {
button.innerHTML = elements[element].name;
}
else {
button.innerHTML = element.replace(/_/g, " ");
}
2021-12-23 00:21:51 -05:00
//capitalize first letter of each word
button.innerHTML = button.innerHTML.replace("."," ").replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}).replace(" ",".").replace(/ /g, "");
//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(", ")+")";
}
else {
button.style.background = elements[element].color;
var colorObject = elements[element].colorObject;
if ((colorObject.r+colorObject.g+colorObject.b)/3 > 200) {
button.className += " bright"
}
}
button.id = "elementButton-" + element;
button.onclick = function() {
selectElement(this.getAttribute("element"));
}
2021-12-28 17:44:28 -05:00
// on right click, show the element's info
button.oncontextmenu = function(e) {
e.preventDefault();
showInfo(this.getAttribute("element"));
}
2021-12-23 00:21:51 -05:00
categoryDiv.appendChild(button);
}
2021-12-28 17:44:28 -05:00
// Set the first button in categoryControls div to be the current category
document.getElementById("categoryControls").children[0].click()
2021-12-23 00:21:51 -05:00
document.getElementById("extraInfo").innerHTML += "< p > < small > There are " + elementCount + " elements, including " + hiddenCount + " hidden ones.< / small > < / p > ";
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();
}
}
}
< / script >
< / head >
< body >
< h1 class = "pagetitle" >
< a href = "https://R74n.com" class = "backbutton" > < < / a >
2021-12-28 17:44:28 -05:00
Sandboxels< / h1 >
2021-12-23 00:21:51 -05:00
< div id = "gameDiv" >
< canvas id = "game" width = "800" height = "600" oncontextmenu = "return false;" >
Your browser does not support the HTML5 canvas tag.
< / canvas >
< div id = "underDiv" >
< div id = "stats" > < / div >
< div id = "controls" >
< div id = "toolControls" >
2021-12-28 17:44:28 -05:00
< 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" > Step< / button > < button id = "sizeDownButton" title = "Decrease the brush size" class = "controlButton" onclick = "mouseSize -= 2;if (mouseSize < 1) { mouseSize = 1; };focusGame();" > -< / button > < button id = "sizeUpButton" title = "Increase the brush size" class = "controlButton" onclick = "mouseSize += 2;if (mouseSize > (height > width ? height : width)) { mouseSize = (height > width ? height : width); };focusGame();" > +< / button > < button id = "resetButton" title = "Clear the entire scene" class = "controlButton" onclick = "if (confirm('Are you sure you want to clear the whole scene?')) {clearAll();};focusGame();" > Reset< / button > < button id = "replaceButton" title = "Override existing pixels when placing" class = "controlButton" onclick = 'if (placeMode == "replace") {placeMode = null;this.setAttribute("on","false");}else {placeMode = "replace";this.setAttribute("on","true");};focusGame();' on = "false" > Replace< / button > < button id = "elemSelectButton" title = "Select an element by ID" class = "controlButton" onclick = 'chooseElementPrompt();focusGame();' > E< / button > < button id = "tpsButton" title = "Change the simulation Ticks Per Second (TPS)" class = "controlButton" onclick = 'var newtps = 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 || newtps == "" || newtps == "0") {alert("You did not enter a valid TPS. The TPS will be reset.");tps = 30;}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)) {alert("You did not enter a valid TPS. The TPS will be reset.");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 (!showingInfo){showInfo(currentElement)}else{closeInfo()};' on = "false" > Info< / button >
2021-12-23 00:21:51 -05:00
< / div >
2021-12-28 17:44:28 -05:00
< div id = "category-tools" category = "tools" style = "display: block;" > < / div >
< div id = "categoryControls" > < / div >
2021-12-23 00:21:51 -05:00
< div id = "elementControls" > < / div >
< / div >
2021-12-28 21:27:54 -05:00
< div id = "extraInfo" > < small > < a href = "controls.txt" target = "_blank" > Controls< / a > • < a href = "changelog.txt" target = "_blank" > Changelog< / a > • < a href = "https://docs.google.com/document/d/1R8xljj_J-K5oU-9y4louwplQmM-ZBvUfXmhbgj5LYdk/edit?usp=sharing" target = "_blank" > Feedback< / a > < / small > < / div >
2021-12-23 00:21:51 -05:00
< / div >
< / div >
2021-12-28 17:44:28 -05:00
< div id = "infoScreen" > <!-- Element Info Page -->
< button id = "infoX" onclick = "closeInfo();" > -< / button >
< span id = "infoTitle" > Title< / span >
< div id = "infoText" > Text< / div >
< input type = "text" id = "infoSearch" placeholder = "Element..." oninput = "showInfo(this.value);" > < / input >
< / div >
2021-12-23 00:21:51 -05:00
<!-- i like having this but ublock blocks these things anyway -->
<!-- Global site tag (gtag.js) - Google Analytics -->
2021-12-29 20:57:33 -05:00
< script async src = "https://www.googletagmanager.com/gtag/js?id=G-T6E9BCPM32" > < / script >
2021-12-23 00:21:51 -05:00
< script >
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
2021-12-29 20:57:33 -05:00
gtag('config', 'G-T6E9BCPM32');
2021-12-23 00:21:51 -05:00
< / script >
< / body >
2021-12-23 01:21:38 -05:00
< / html >