Merge branch 'R74nCom:main' into main

This commit is contained in:
PumpkinPriest 2023-06-03 21:51:10 -04:00 committed by GitHub
commit e3b2bbc6c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 2480 additions and 160 deletions

1380
changelog.html Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,85 @@
See sneak peaks for upcoming updates on the Discord: https://discord.gg/ejUc6YPQuS
A fancier version of this changelog can be found here: https://sandboxels.r74n.com/changelog
[Version 1.8.3 - May 26, 2023 - Deserted Update]
+ Cactus
+ Fancy Changelog and Controls pages
+ Toggle Burning setting
+ Broth Ice (Hidden)
+ Rad Shard (Hidden)
+ Linked to our official Sandboxels Wiki on wiki.gg (https://sandboxels.wiki.gg/)
[Changes]
+ Cacti and Charcoal now spawn in Desert world gen
+ Petals will fall slowly if detached from flower
+ Pointer color can be customized
+ Bless grows Grass on Dirt
+ Frogs can somewhat swim
+ Pool Water can kill Frogs and Seeds
+ Pool Water will break down Blood and Poison
+ Cream releases Steam when boiling
+ Cream can wet soil
+ Popcorn pops when made from Corn
+ Melted Butter stains solids
+ Mushroom parts break into Mycelium
+ Eggs melting leaves behind Sulfur Gas
+ Eggs won't break when dropped on soft material
+ Bless turns Molten Lead to Molten Gold
+ Unique fire colors for Molten Copper, Lead, Zinc, Salt, and Calcium
+ Broth can be made from Bones and Mushroom parts
+ Unique Broth color for soups with Flowers, Potato, Rotten Meat, Cheese, Beans, Wheat, Algae
+ Milk and Cream can be churned to Butter
+ Rats can eat Eggnog
+ Fish eat Yolk and Cell
+ Ants can drink Juice
+ Soap kills bugs
+ Ozone kills Plant
+ Charcoal, Roots, Hyphae, and Amalgam conduct electricity
+ Rad Glass has a texture when placed manually
+ Rad Glass can be made with Fallout
+ LEDs melt into Gallium
+ Molten Calcium can burn
+ Salt alias 'Sodium Chloride'
+ Anesthesia alias 'Nitrous Oxide'
+ Anesthesia turns Clouds to Acid Clouds
+ Anesthesia depletes Ozone
+ Sulfur alias 'Sulphur'
+ TNT alias 'Trinitrotoluene'
+ DNA alias 'Deoxyribonucleic Acid'
+ DNA from Cancer appears corrupted
+ Potatoes can explode when radiated
+ Cellulose freezes into Paper
+ Bees can be crushed into Honey
+ Bamboo and Vines can convert Carbon Dioxide to Oxygen
+ Flour can be wet by Pool Water, Milk, Cream, Broth, Soda, Tea, Blood, Antibody, and Infection
+ Slag can be made with Smog, Pyrocumulus, Dioxin, and Poison Gas
+ Cream changes color when mixed with Milk variant ingredients
+ Radiation affects Aluminum, Pool Water, Soda, Broth, and Tea
+ Pistils can be broken
+ Sugar and Candy dissolve in Soda
+ Bleach and Yeast reaction generates heat
+ Bleach and Soap reaction
+ Bleach breaks down Antidote
+ Sponge creates Bubbles when absorbing Soap
~ Potatoes, Straw, Wheat, and Worms burn slower
~ Sap boils at a lower point
~ Strange Matter is now a liquid
~ Bless turns Soda into Seltzer
~ Cellulose burns less
~ Recolored Frozen Meat
~ Adjusted Sulfur Gas density
~ Adjusted Molten Gallium density
[Bug Fixes]
~ Fixed: Grape Juice and Potato Juice turns yellow when frozen
~ Fixed: Color-customizable elements don't show selector if hidden
~ Fixed: Foam created by other foam takes air temperature
[Technical]
+ Element property glow for gas effect (true/false)
+ LIGHTWEIGHT behavior preset
+ Reaction properties burning1 and burning2 requirement (true/false)
~ Seeds element now uses eLists.SEEDS
[Version 1.8.2 - May 12, 2023 - Very Necessary Update]
+ Lettuce
+ Liquid Light at absolute zero (Hidden)

158
controls.html Normal file
View File

@ -0,0 +1,158 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Sandboxels Controls</title>
<meta name="description" content="How to play the free falling-sand browser game.">
<meta name="keywords" content="falling sand, elements, pixel art, simulator, powder">
<meta name="author" content="R74n">
<meta name="copyright" content="R74n">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="all">
<!--Favicons-->
<link rel="apple-touch-icon" sizes="180x180" href="icons/apple-touch-icon.png?v=2">
<link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png?v=2">
<link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png?v=2">
<link rel="manifest" href="manifest.json">
<link rel="mask-icon" href="icons/safari-pinned-tab.svg?v=2" color="#2167ff">
<link rel="shortcut icon" href="icons/favicon.ico?v=2">
<meta name="msapplication-TileColor" content="#e6d577">
<meta name="theme-color" content="#000000">
<!--OpenGraph-->
<meta property="og:locale" content="en_US">
<meta property="og:type" content="website">
<meta property="og:title" content="Sandboxels Controls">
<meta property="og:description" content="How to play the free falling-sand browser game.">
<meta property="og:url" content="https://sandboxels.r74n.com">
<meta property="og:site_name" content="Sandboxels">
<meta property="og:image" content="https://sandboxels.r74n.com/icons/wallpaper.png">
<meta property="og:image:width" content="1980">
<meta property="og:image:height" content="971">
<meta property="og:image:type" content="image/png">
<meta property="og:image:alt" content="A rainforest made in Sandboxels">
<!--Twitter-->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:description" content="How to play the free falling-sand browser game.">
<meta name="twitter:title" content="Sandboxels Controls">
<meta name="twitter:site:id" content="1436857621827530753">
<meta name="twitter:image" content="https://sandboxels.r74n.com/icons/card.png">
<meta name="twitter:image:alt" content="A rainforest made in Sandboxels">
<meta name="twitter:creator:id" content="1436857621827530753">
<link rel="stylesheet" type="text/css" href="style.css?nocache=3">
<style>
/* on mobile, make h1 fit on one line */
@media only screen and (max-width: 800px) {
h1 {
font-size: 1em;
}
}
#controls {
font-family: Arial, Helvetica, sans-serif
}
td:nth-child(odd) {
font-weight: bold;
}
table {
margin-left: auto;
margin-right: auto;
}
th {
text-align: center;
font-weight: bold;
}
h2 { text-align: center; }
</style>
</head>
<body>
<h1><a href="https://sandboxels.R74n.com" class="backbutton" target="_blank">&lt;</a> Sandboxels Controls</h1>
</ul>
<div id="controls">
<h2>Keyboard/Mouse Controls</h2>
<table>
<thead><tr><th>Function</th><th>Control</th></tr></thead>
<tr><td>Draw pixels</td> <td><kbd>Left Click</kbd></td></tr>
<tr><td>Erase pixels</td> <td><kbd>Right Click</kbd></td></tr>
<tr><td>Pick element</td> <td><kbd>Middle Click</kbd></td></tr>
<tr><td>Pause simulation</td> <td><kbd>Space</kbd> or <kbd>P</kbd></td></tr>
<tr><td>Intensify effect</td> <td><kbd>Shift</kbd> + <kbd style="background-color:red;">Heat</kbd>/<kbd style="background-color:blue;">Cool</kbd>/<kbd style="background-color:#fff4b5;color:black">Mix</kbd>/<kbd style="background-color:yellow;color:black">Shock</kbd>/<kbd style="background-color:888888;color:white">Smash</kbd></td></tr>
<tr><td>Draw line</td> <td><kbd>Shift</kbd> + <kbd>Click</kbd></td></tr>
<tr><td>Change cursor size</td> <td><kbd>Scroll</kbd> or <kbd>+</kbd><kbd>-</kbd> or <kbd>[</kbd><kbd>]</kbd></td></tr>
<tr><td>Cursor size 1</td> <td><kbd>Shift</kbd> + <kbd>-</kbd></td></tr>
<tr><td>Cursor size +15</td> <td><kbd>Shift</kbd> + <kbd>+</kbd></td></tr>
<tr><td>Change category</td> <td><kbd></kbd><kbd></kbd></td></tr>
<tr><td>Select by name</td> <td><kbd>E</kbd></td></tr>
<tr><td>Element info</td> <td><kbd>I</kbd> or <kbd>/</kbd></td></tr>
<tr><td>Open settings</td> <td><kbd>\</kbd></td></tr>
<tr><td>Open Mod Manager</td> <td><kbd>M</kbd></td></tr>
<tr><td>Reset canvas</td> <td><kbd>R</kbd></td></tr>
<tr><td>Single step</td> <td><kbd>&gt;</kbd></td></tr>
<tr><td>Fullscreen</td> <td><kbd>F</kbd> or <kbd>F11</kbd></td></tr>
<tr><td>Normal view</td> <td><kbd>1</kbd></td></tr>
<tr><td>Thermal view</td> <td><kbd>2</kbd></td></tr>
<tr><td>Basic view (No effects)</td> <td><kbd>3</kbd></td></tr>
<tr><td>Smooth view (Low performance)</td> <td><kbd>4</kbd></td></tr>
<tr><td>Toggle GUI</td> <td><kbd>F1</kbd></td></tr>
<tr><td>Capture screenshot</td> <td><kbd>C</kbd> or <kbd>F2</kbd></td></tr>
</table>
<h2>Button Info</h2>
<table>
<thead><tr><th>Button</th><th>Function</th></tr></thead>
<tr><td>Pause</td> <td>Pause/play the simulation</tr>
<tr><td>Step</td> <td>Run a single frame of simulation</tr>
<tr><td>Minus (-)</td> <td>Decrease the cursor size</tr>
<tr><td>Plus (+)</td> <td>Increase the cursor size</tr>
<tr><td>Reset</td> <td>Clear the entire canvas</tr>
<tr><td>Replace</td> <td>Override existing pixels when placing</tr>
<tr><td>E</td> <td>Select any element by name</tr>
<tr><td>TPS</td> <td>Change how fast the simulation runs (Default 30tps)</tr>
<tr><td>Info</td> <td>Open the element info screen</tr>
<tr><td>Mods</td> <td>Open the Mod Manager</tr>
<tr><td>Settings</td> <td>Open the Settings Menu</tr>
</table>
<h2>Stats Bar Info</h2>
<table>
<thead><tr><th>Text</th><th>Function</th></tr></thead>
<tr><td>x123,y123</td> <td>Coordinates of the cursor's center</tr>
<tr><td>Pxls:123</td> <td>Amount of pixels currently on-screen</tr>
<tr><td>30tps</td> <td>Simulation ticks attempted to run per second</tr>
<tr><td>1234</td> <td>Total amount of ticks simulated</tr>
<tr><td>[↑ ] or [ ↑]</td> <td>Shift is held down</tr>
<tr><td>[A ] or [ A]</td> <td>Alt/Option is held down</tr>
<tr><td>ELEM:SAND</td> <td>Pixel currently hovered over</tr>
<tr><td>Temp:20°C</td> <td>Temperature of the pixel</tr>
<tr><td>C1, C0.75, ...</td> <td>Electric charge of the pixel</tr>
</table>
<p>The original <a href="https://r74n.com/controls.txt">plain text version</a> may not be maintained.</p>
</div>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-93720349-9"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-93720349-9');
</script>
</body>
</html>

View File

@ -1,3 +1,5 @@
A fancier version of this can be found here: https://sandboxels.r74n.com/controls
[Sandboxels Controls]
Left Click = Place Pixels
Right Click = Erase Pixels
@ -32,13 +34,13 @@ F2 or C = Capture Screenshot
[Button Info]
Pause = Pause/play the simulation
Step = Run a single frame
Step = Run a single frame of simulation
Minus = Decrease the cursor size
Plus = Increase the cursor size
Reset = Clears the entire simulation
Replace = Overrides pixels when placing
Reset = Clear the entire simulation
Replace = Override existing pixels when placing
E = Select any element by name
TPS = Change how fast the simulation runs
Info = Brings up the element info screen
Mods = Opens the Mod Manager
Settings = Opens the Settings Menu
Info = Open the element info screen
Mods = Open the Mod Manager
Settings = Open the Settings Menu

File diff suppressed because it is too large Load Diff

View File

@ -105,4 +105,5 @@ if (elements.glass) {elements.glass.color = ["#5e807d","#679e99"];}
if (elements.rad_glass) {elements.rad_glass.color = ["#648c64","#6aad83"];}
if (elements.packed_sand) {elements.packed_sand.color = "#a1975d";}
if (elements.dough) {elements.dough.color = "#edd8ba";}
if (elements.flour) {elements.flour.color = "#f0e2b7";}
if (elements.flour) {elements.flour.color = "#f0e2b7";}
if (elements.frozen_meat) {elements.frozen_meat.color = "#65b8aa";}

40
mods/hidden_ground.js Normal file
View File

@ -0,0 +1,40 @@
// Hidden Ground v1.0
// Author: Melecie
runAfterLoad(function() {
if (enabledMods.includes("mods/the_ground.js")) {
let regexRocks = /(granite)|(rhyolite)|(pumice)|(obsidian)|(dacite)|(dacidian)|(andesite)|(diorite)|(scoria)|(andesidian)|(gabbro)|(basalt)|(basalidian)|(peridotite)|(komatiite)|(komatidian)/
let regexType = /(_gravel)|(_sand)|(_dust)|(_shard)|(hot_)/
let toHide = ["dry_permafrost", "hot_sand", "hot_dirt", "hot_rock", "hot_rock_wall", "hot_gravel", "hot_limestone", "hot_calcium_carbonate_dust", "sandy_water", "clay_water", "dry_clay_loam"]
// hides all elements part of both rocks and type
// false positives *can* be hit because this doesn't check if it comes from The Ground (it can't), but ideally none given how specific it is
for (elem in elements) {
if (regexRocks.test(elem)) {
// move wall to solids to not make land too big
if (/_wall/.test(elem)) {
elements[elem].category = "solids"
}
// hide the rest
if (regexType.test(elem)) {
elements[elem].hidden = true;
}
}
}
// manual hiding
for (elem in toHide) {
elements[toHide[elem]].hidden = true;
}
// while i'm here, might as well fix Sandstone's color
elements.sandstone.color = "#dbbe80";
}
else {
enabledMods.splice(enabledMods.indexOf("mods/hidden_ground.js"), 1);
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
alert("Hidden Ground: This mod requires The Ground mod. Removing mod and reloading.");
window.location.reload();
}
})

285
mods/machines.js Normal file
View File

@ -0,0 +1,285 @@
elements.led_w = {
behavior: behaviors.WALL,
reactions: {
"light": { "charge1": 1 }
},
color: "#c0c0c0",
colorOn: "#ffffff",
category: "machines",
tempHigh: 1500,
stateHigh: "molten_glass",
conduct: 1
};
elements.ledO = {
behavior: behaviors.WALL,
reactions: {
"light": { "charge1": 1 }
},
color: "#b06000",
colorOn: "#ff8c00",
category: "machines",
tempHigh: 1500,
stateHigh: "molten_glass",
conduct: 1
};
elements.ledY = {
behavior: behaviors.WALL,
reactions: {
"light": { "charge1": 1 }
},
color: "#b0b000",
colorOn: "#ffff00",
category: "machines",
tempHigh: 1500,
stateHigh: "molten_glass",
conduct: 1
};
elements.ledP = {
behavior: behaviors.WALL,
reactions: {
"light": { "charge1": 1 }
},
color: "#551a8b",
colorOn: "#800080",
category: "machines",
tempHigh: 1500,
stateHigh: "molten_glass",
conduct: 1
};
elements.esuperheater = {
color: "#ff69b4",
behavior: behaviors.WALL,
behaviorOn: elements.superheater.behavior,
category: "machines",
insulate: elements.wire.insulate,
conduct: elements.wire.conduct,
noMix: elements.wire.noMix
};
elements.eheater = {
color: "#FA8072",
behavior: behaviors.WALL,
behaviorOn: elements.heater.behavior,
category: "machines",
insulate: elements.wire.insulate,
conduct: elements.wire.conduct,
noMix: elements.wire.noMix
};
elements.ecooler = {
color: "#AFEEEE",
behavior: behaviors.WALL,
behaviorON: elements.cooler.behavior,
category: "machines",
insulate: elements.wire.insulate,
conduct: elements.wire.conduct,
noMix: elements.wire.noMix
};
elements.efreezer = {
color: "#E0FFFF",
behavior: behaviors.WALL,
behaviorOn: elements.freezer.behavior,
category: "machines",
insulate: elements.wire.insulate,
conduct: elements.wire.conduct,
noMix: elements.wire.noMix
};
elements.fire_sensor = {
behavior: behaviors.WALL,
reactions: {
"fire": {"charge1":1},
"plasma": {"charge1":1},
"cold_fire": {"charge1":1},
"fireball": {"charge1":1},
"antifire": {"charge1":1},
},
color: "#FFA500",
colorOn: "#FFBF00",
category: "machines",
conduct: 1
};
elements.light_sensor = {
behavior: behaviors.WALL,
reactions: {
"light": {"charge1":1},
"liquid_light": {"charge1":1},
"flash": {"charge1":1},
"radiation": {"charge1":1},
"laser": {"charge1":1},
},
color: "#FFFFFF",
category: "machines",
conduct: 1
};
elements.water_sensor = {
behavior: behaviors.WALL,
reactions: {
"water": {"charge1":1},
"salt_water": {"charge1":1},
"sugar_water": {"charge1":1},
"seltzer": {"charge1":1},
"dirty_water": {"charge1":1},
"pool_water": {"charge1":1},
"slush": {"charge1":1},
"hail": {"charge1":1},
"ice": {"charge1":1},
"salt_ice": {"charge1":1},
"sugar_ice": {"charge1":1},
"seltzer_ice": {"charge1":1},
"dirty_ice": {"charge1":1},
"pool_ice": {"charge1":1},
"steam": {"charge1":1},
"cloud": {"charge1":1},
"rain_cloud": {"charge1":1},
"snow_cloud": {"charge1":1},
"hail_cloud": {"charge1":1},
"thunder_cloud": {"charge1":1},
"pool_ice": {"charge1":1},
},
color: "#89CFF0",
category: "machines",
conduct: 1
};
elements.mega_shocker = {
behavior: behaviors.WALL,
behaviorOn: [
"XX|XX|XX",
"XX|XX|XX",
"XX|CR:lightning AND SH|XX",
],
color: "#C3B1E1",
category: "machines",
conduct: 1
};
elements.exploder = {
behavior: behaviors.WALL,
behaviorOn: [
"XX|CR:explosion AND SH|XX",
"CR:explosion AND SH|XX|CR:explosion AND SH",
"XX|CR:explosion AND SH|XX",
],
color: "#ff8c00",
category: "machines",
conduct: 1,
hardness: 1
};
elements.evoid = {
behavior: behaviors.WALL,
behaviorOn: [
"XX|DL|XX",
"DL|XX|DL",
"XX|DL|XX",
],
color: "#434854",
category: "machines",
conduct: 1,
hardness: 1,
ignore: ["wire","battery"]
};
elements.eburner = {
behavior: behaviors.WALL,
behaviorOn: [
"CR:propane|CR:propane|CR:propane",
"XX|XX|XX",
"XX|XX|XX",
],
color: "#fadecd",
category: "machines",
conduct: 1
};
elements.mega_led = {
behavior: behaviors.WALL,
reactions: {
"light": { "charge1": 1 }
},
color: ["#660000","#b06000","#b0b000","#006600","#000066","#551a8b"],
colorOn: ["#ff0000","#ff8c00","#ffff00","#00ff00","#0000ff","#800080"],
category: "machines",
tempHigh: 15000,
stateHigh: "molten_stained_glass",
conduct: 1,
state: "gas"
};
elements.estatic = {
behavior: behaviors.WALL,
color: "#3d3d3d",
colorOn: ["#ffffff","#888888","#000000"],
category: "machines",
conduct: 1
};
elements.elattice = {
behavior: behaviors.WALL,
behaviorOn: [
"CL|XX|CL",
"XX|XX|XX",
"CL|XX|CL",
],
color: "#e795f0",
colorOn: ["#7110e8","#2c00b0","#000cb0"],
category: "machines",
conduct: 1
};
elements.esnake = {
behavior: behaviors.WALL,
behaviorOn: [
"XX|XX|XX",
"XX|LB:plant AND RT%5|M1 AND BO:1,2,3",
"XX|XX|XX",
],
color: "#00bf00",
category: "machines",
conduct: 1,
rotatable: true
};
elements.evertical = {
behavior: behaviors.WALL,
behaviorOn: [
"XX|M1|XX",
"CR:wall|XX|CR:wall",
"XX|XX|XX",
],
color: "#e8e6e6",
category: "machines",
conduct: 1
};
elements.ehorizontal = {
behavior: behaviors.WALL,
behaviorOn: [
"XX|CR:wall|XX",
"XX|XX|M1",
"XX|CR:wall|XX",
],
color: "#e8e6e6",
category: "machines",
conduct: 1
};
elements.ultrasuper_exploder = {
behavior: behaviors.WALL,
behaviorOn: [
"XX|CR:supernova AND SH|XX",
"CR:supernova AND SH|XX|CR:supernova AND SH",
"XX|CR:supernova AND SH|XX",
],
color: "#4103fc",
category: "machines",
conduct: 1,
hardness: 1
};
elements.tiny_exploder = {
behavior: behaviors.WALL,
behaviorOn: [
"XX|CR:pop AND SH|XX",
"CR:pop AND SH|XX|CR:pop AND SH",
"XX|CR:pop AND SH|XX",
],
color: ["#ffb48f","#ffd991","#ffad91"],
category: "machines",
conduct: 1,
hardness: 1
};
elements.poop = {
color: "#8B4513",
behavior: behaviors.POWDER,
category: "life",
state: "solid",
tempHigh: 100,
stateHigh: "stench"
};

View File

@ -385,6 +385,35 @@ function doFinalChecks() {
if (!elements[elements[key].breakInto]) { delete elements[key].breakInto; }
}
}
if (elements[key].colorPattern) {
if (!elements[key].colorKey) {
delete elements[key].colorPattern;
}
else {
var newPattern = [];
for (var i = 0; i < elements[key].colorPattern.length; i++) {
newPattern.push([]);
var line = elements[key].colorPattern[i];
// loop through each character in the line
for (var j = 0; j < line.length; j++) {
var char = line[j];
if (elements[key].colorKey[char]) {
if (elements[key].colorKey[char].startsWith("#")) {
var rgb = hexToRGB(elements[key].colorKey[char]);
elements[key].colorKey[char] = "rgb("+rgb.r+","+rgb.g+","+rgb.b+")";
}
newPattern[i].push(elements[key].colorKey[char]);
}
else {
newPattern[i].push("rgb(255,255,255)");
}
}
}
elements[key].colorPattern = newPattern;
delete elements[key].colorKey;
}
}
}
};

19
mods/vibranium.js Normal file
View File

@ -0,0 +1,19 @@
};
elements.vibranium
color:"#455357",
behavior: behaviors.WALL,
category: "solids",
state: "solid",
tempHigh: 1000000000,
conduct: Infinity,
hardness: 1,
};
elements.uru
color: "#719aa6",
behavior: behaviors.WALL,
catagory: "solids",
state: "solid",
tempHigh: 1000000000,
conduct: 0,
Hardness: 1,
};

View File

@ -540,4 +540,4 @@ if(enabledMods.includes(onTryMoveIntoMod) && enabledMods.includes(libraryMod)) {
enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod);
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
alert(`The ${onTryMoveIntoMod} mod and ${libraryMod} mods are required and have been automatically inserted (reload for this to take effect).`);
};
};

View File

@ -1,2 +1,4 @@
https://sandboxels.r74n.com/
https://sandboxels.r74n.com/lite
https://sandboxels.r74n.com/lite
https://sandboxels.r74n.com/changelog
https://sandboxels.r74n.com/controls