From 839e89fed2cca0f1d55b66d99d7d921e7c0529cd Mon Sep 17 00:00:00 2001 From: Alexthetransfem <124483815+theenchantedsword@users.noreply.github.com> Date: Tue, 1 Jul 2025 20:52:48 -0500 Subject: [PATCH 1/3] Update and rename mods/betaworldgen.js to worldgenlibrary.js betaworldgen.js is no longer in the beta, and to differentiate itself more from the "worldgen_test.js" mod, it has taken the label of a library as it simplifies world generation allowing mod makers to use this to make new biomes, although it can be used for fun and not solely for mod making. it also includes ore vein generation and has a biome specific to the plants.js mod. --- mods/betaworldgen.js | 187 ------------------------------------------- worldgenlibrary.js | 161 +++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+), 187 deletions(-) delete mode 100644 mods/betaworldgen.js create mode 100644 worldgenlibrary.js diff --git a/mods/betaworldgen.js b/mods/betaworldgen.js deleted file mode 100644 index 33561e42..00000000 --- a/mods/betaworldgen.js +++ /dev/null @@ -1,187 +0,0 @@ -//This mod was made by Adora the transfem, https://discord.com/users/778753696804765696 on discord and https://www.tiktok.com/@alextheagenenby?_t=8hoCVI3NRhu&_r=1 on tiktok. -let code = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10, k: 11, l: 12, m: 13, n: 14, o: 15, p: 16, q: 17, r: 18, s: 19, t: 20, u: 21, v: 22, w: 23, x: 24, y: 25, z: 26, A: 27, B: 28, C: 29, D: 30, E: 31, F: 32, G: 33, H: 34, I: 35, J: 36, K: 37, L: 38, M: 39, N: 40, O: 41, P: 42, Q: 43, R: 44, S: 45, T: 46, U: 47, V: 48, W: 49, X: 50, Y: 51, Z: 52 } -let invertedCode = {} -let flat = function(){ - let str = ""; - for(var i = 0; i < width; i++){ - str += "a"; - } - return str; -} -let biomes = { - plains: { - layers: 2, - thicknesses: [15, 10], - specificSeeds: "flat", - heights: [1, 21], - layersObj: { - 1: ["rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","iron","iron","iron","aluminum","aluminum","aluminum","aluminum","uranium","diamond","copper","copper","copper","copper","sodium","sodium","potassium","potassium","charcoal","charcoal","charcoal","charcoal","charcoal", "calcium"], - 2: ["dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt","dirt", "dirt", "dirt","dirt", "dirt", "gravel", "gravel"] - }, - ssHeight: 39, - ssElems: ["grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","sapling","pinecone","seeds","seeds"] - }, - desert: { - layers: 1, - thicknesses: [20], - specificSeeds: "flat", - heights: [1], - layersObj: { - 1: ["sand"] - }, - ssHeight: 40, - ssElems: [undefined,undefined,undefined,undefined,undefined,undefined,"cactus"] - }, - forest: { - layers: 2, - specificSeeds: "flat", - heights: [1, 16], - thicknesses: [15, 10], - ssHeight: 29, - layersObj: { - 1: ["rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","charcoal","charcoal","charcoal","charcoal","charcoal","iron","iron","iron","aluminum","aluminum","aluminum","calcium","calcium","sodium","potassium","diamond"], - 2: ["dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","gravel"] - }, - ssElems: ["grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","sapling", "pinecone"], - } -} -for (var item in code){ - invertedCode[code[item]] = item; -} -let ranNum = function(max, last) { - // Calculate a bias factor - let bias = Math.random() * 0.07 + 0.5; // Adjust this range to control the bias strength - - // Generate a biased random number towards the 'last' value - let num = Math.round(bias * last + (1 - bias) * Math.random() * max) + 1; - - // Randomly assign a negative or positive sign - return (Math.random() > 0.5) ? num : -num; -} -function decode(str){ - let result = []; - str.split(""); - for(var i = 0; i < str.length; i++){ - if(code[str[i]]){ - if(str[i - 1] == "*"){ - result[i] = code[str[i]] * 2; - } else { - result[i] = code[str[i]]; - } - } else if(str[i] == ":"){ - result[i] = ":"; - } else {continue;} - } - return result.filter(element => element !== undefined); -} -function makeSeed(layers, thickness){ - let result = ""; - for(var i = 0; i < layers; i++){ - let avgThickness = thickness[i]; - let str = ""; - let lastNum = 0; - for(var ii = 1; ii <= width-1; ii++){ - let num = ranNum(4, lastNum); - let cThickness = avgThickness + num; - lastNum = num; - if(invertedCode[cThickness] != undefined){ - str += invertedCode[cThickness]; - } else { - let num = Math.round(cThickness / 2); - str += `*${invertedCode[num]}`; - } - } - result += (i == (layers - 1)) ? str : `${str}:`; - } - return result; -} -function splitArrayByCharacter(arr, char) { - let result = []; - let subArray = []; - - arr.forEach(element => { - if (element === char) { - result.push(subArray); - subArray = []; - } else { - subArray.push(element); - } - }); - - // Push the last subarray if it's not empty - if (subArray.length > 0) { - result.push(subArray); - } - - return result; -} -let seed = ""; -function generate(type, seed1 = undefined){ - if(seed1){ - seed = seed1; - } else{ - seed = makeSeed(biomes[type].layers, biomes[type].thicknesses); - } - let semifinalArr = decode(seed); - let finalArr = splitArrayByCharacter(semifinalArr, ":"); - for(var i = 0; i < finalArr.length; i++){ - let lHeight = biomes[type].heights[i]; - for(var ii = 1; ii < width-1; ii++){ - for(var iii = (height - 1) - lHeight; iii > height - lHeight - finalArr[i][ii]; iii--){ - let x = ii; - let y = iii; - let Num = Math.round(Math.random() * biomes[type].layersObj[i+1].length); - if(Num == biomes[type].layersObj[i+1].length){Num-=1;} - let element = biomes[type].layersObj[i+1][Num]; - if(isEmpty(x, y) && !outOfBounds(x, y)){ - createPixel(element, x, y); - } else {console.log("could not place. " + x + ", " + y); continue;} - } - } - } - if(biomes[type].specificSeeds){ - if(biomes[type].specificSeeds == "flat"){ - for(var i = 1; i < width-1; i++){ - let y = height - biomes[type].ssHeight; - let Num = Math.round(Math.random() * biomes[type].ssElems.length); - if(Num == biomes[type].ssElems.length){Num-=1;} - let element = biomes[type].ssElems[Num]; - if(element == undefined){continue;} - if(isEmpty(i, y) && !outOfBounds(i, y)){ - createPixel(element, i, y); - } - } - } - } -} -elements.copy_seed = { - category: "tools", - onSelect: function(pixel){ - navigator.clipboard.writeText(seed).then(function() { - alert(`Seed succesfully copied to clipboard!`); - }).catch(function(error) { - alert("Unable to copy text.") - }); - - } -} -elements.random_generation = { - category: "tools", - onSelect: function(pixel){ - autoResizeCanvas(); - focusGame(); - let type = prompt("Enter the biome you want to generate: \nOptions: plains, desert, forest"); - if(!biomes[type]) {type = "plains";} - generate(type); - } -} -elements.seed_generation = { - category: "tools", - onSelect: function(pixel){ - autoResizeCanvas(); - focusGame(); - let type = prompt("Enter the biome you want to generate: \nOptions: plains, desert, forest"); - let seed1 = prompt("Enter the seed: "); - generate(type, seed1); - } -} diff --git a/worldgenlibrary.js b/worldgenlibrary.js new file mode 100644 index 00000000..5fe60643 --- /dev/null +++ b/worldgenlibrary.js @@ -0,0 +1,161 @@ +Array.prototype.getClosest = function(num){ + let arr = []; + for(value of this){ + arr[arr.length] = Math.abs(num-value); + }; + return this[arr.indexOf(Math.min(...arr))]; +} +function biasedNum(min, max, bias, strength = 0.75){ + let num = (Math.random()*(max-min))+min; + num += Math.random()*1*Math.round((bias-num)); + return num; +} +function generateSeed(min, max, base, bias){ + let arr = []; + for(let i = 0; i <= width; i++){ + arr[i] = Math.round(biasedNum(min, max, base, bias)); + base = arr[i]; + } + return arr; +} +let vChance = { + coal: 0.25, + copper: 0.25, + tin: 0.25, + aluminum: 0.2, + iron: 0.175, + zinc: 0.17, + lead: 0.14, + nickel: 0.13, + uranium: 0.12, + diamond: 0.06, + gold: 0.2, +}; +let vMultipliers = { + dirt: 1, + sand: 0.25, +} +class biome { + constructor(layersArr, yLevels, vMulti = 1, afterFunc = false){ + this.layers = layersArr; + this.yLevels = yLevels; + this.vMulti = vMulti; + this.generate = function(seed){ + autoResizeCanvas(); + if(!paused){togglePause();} + for(let x = 0; x <= width; x++){ + for(let y = 0; y <= seed[width]; y++){ + let layerHeight = this.yLevels.getClosest(y), layerNum = this.yLevels.indexOf(layerHeight); + let layer = this.layers[layerNum]; + let chance = (y-layerHeight)/11; + let elem = layer[Math.round(Math.random()*layer.length)]; + if(chance < 0 && (this.layers[layerNum-1] != undefined) && Math.random() <= chance){ + layer = this.layers[layerNum-1]; + elem = layer[Math.round(Math.random()*layer.length)]; + } else if(chance > 0 && (this.layers[layerNum+1] != undefined) && Math.random() <= chance){ + layer = this.layers[layerNum+1]; + elem = layer[Math.round(Math.random()*layer.length)]; + } + if(isEmpty(x,y) && !outOfBounds(x,y)){ + createPixel(elem, x, height-y); + if(elem == "sapling"){ + if(this.wc){ + pixelMap[x][height-y].wc = this.wc; + } + if(this.lc){ + pixelMap[x][height-y].lc = this.lc; + } + } + } + } + } + setTimeout(function(){ + for(let i = 30; i > 0; i--){ + doFrame(); + focusGame(); + } + for(let x = 0; x <= width; x++){ + for(let y = 0; y <= height; y++){ + if(!isEmpty(x,y) && !outOfBounds(x,y) && ["rock","sand"].includes(pixelMap[x][y].element)){ + for(let coords of squareCoords){ + let x2 = x + coords[0], y2 = y + coords[1]; + if(!isEmpty(x2,y2) && !outOfBounds(x2,y2) && vChance[pixelMap[x2][y2].element] != undefined){ + let chance = (vChance[pixelMap[x2][y2].element]*vMultipliers[pixelMap[x][y].element])*(this.vMulti || 1); + if(Math.random() < chance){ + changePixel(pixelMap[x][y], pixelMap[x2][y2].element); + } + } + } + } + } + } + if(afterFunc != false){ + afterFunc(); + } + togglePause(); + }, 50); + }; + } +} +let biomes = { + plains: new biome([["rock","dirt","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","diamond","charcoal", "gold", "charcoal", "copper", "copper", "tin", "tin", "aluminum", "iron", "zinc", "lead", "nickel", "uranium"],["dirt","gravel","clay","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","mud"], ["dirt","dirt","dirt","grass","grass","dirt","dirt","grass","dirt","sapling","pinecone","seeds"]], [13, 32, 35], 1, ()=>{for(i = 0; i < width; i++){if(isEmpty(i, 40) && !outOfBounds(i, 40) && Math.random() < 0.25){createPixel("grass",i,40);}}}), + desert: new biome([["rock","dirt","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","diamond","charcoal", "charcoal", "copper", "copper", "tin", "tin", "aluminum", "iron", "zinc", "lead", "nickel", "uranium", "gold"], ["sand","sand","sand","sand","sand","sand","sand","sand","sand","sand","sand","sand","sand","gold","iron","copper","tin","aluminum","zinc","charcoal"], ["sand"], ["sand","sand","sand","sand","sand","sand","sand","sand","sand","sand","sand","cactus"]], [4, 14, 27, 37], 1, ()=>{for(i = 0; i < width; i++){if(isEmpty(i, 40) && !outOfBounds(i, 40) && Math.random() < 0.0125){createPixel("cactus",i,40);}}}), + savanna: new biome([["rock","clay","clay","clay","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","diamond", "diamond", "charcoal", "charcoal", "gold", "charcoal", "copper", "copper", "copper", "tin", "tin", "aluminum", "iron", "zinc", "lead", "nickel", "uranium"],["dirt","clay","clay","clay","dirt","dirt","dirt","dirt","dirt","dirt","mud"], ["grass","dirt","dirt","sand","sand","sand","dirt","dirt","dirt","sapling","dirt"]], [13, 27, 35], 1.6, ()=>{ + for(let i = 0; i <= width; i++){ + let elemArr = ["grass","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","sapling","dirt"], elem = elemArr[Math.round(Math.random()*elemArr.length)]; + createPixel(elem, i, 40); + if(elem == "sapling"){ + pixelMap[i][40].wc = ["#bdab7e", "#b09c6a", "#ab996d", "#998a63", "#917959", "#877051"]; + pixelMap[i][40].lc = ["#6fde26", "#8eed34", "#8cdb42", "#7bd12a", "#96e81c", "#a9e64e", "#a0d94c", "#a9d63e"]; + } + } + }), + tundra: new biome([["rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","iron","tin","gold","diamond", "diamond", "charcoal", "charcoal", "gold", "charcoal", "copper", "copper", "copper", "tin", "tin", "aluminum", "iron", "zinc", "lead", "nickel", "uranium"],["permafrost","permafrost","permafrost","snow","ice","permafrost","permafrost","permafrost","permafrost","permafrost","permafrost"], ["dirt","dirt","mud","dirt","dirt","snow","dirt","mud","mud","dirt","dirt"]], [7, 16, 27], 1.65, ()=>{ + for(let i = 0; i <= width; i++){ + let elemArr = ["grass","dirt","dirt","dirt"], elem = elemArr[Math.round(Math.random()*elemArr.length)]; + createPixel(elem, i, 40); + }; + }), +}; +biomes.savanna.wc = ["#bdab7e", "#b09c6a", "#ab996d", "#998a63", "#917959", "#877051"]; +biomes.savanna.lc = ["#6fde26", "#8eed34", "#8cdb42", "#7bd12a", "#96e81c", "#a9e64e", "#a0d94c", "#a9d63e"]; +elements.generate = { + category: "tools", + default: "plains", + onSelect: function(){ + let b = []; + for(key in biomes){ + if(!biomes[key].hide){ + b[b.length] = key; + } + } + promptInput("There are the following biomes available: \n"+ b.join(", "), (out)=>{ + if(biomes[out] == undefined){ + alert("Invalid Selection."); + } else { + let seed = generateSeed(27, Math.max(...biomes[out].yLevels)+4, Math.max(...biomes[out].yLevels)+1); + biomes[out].generate(seed); + elements.generate.default = out; + selectElement("dirt"); + } + }, "Enter biome to generate: ", elements.generate.default); + } +} +for(item of enabledMods){ + if(item.includes("plants.js")){ + biomes.orchard = new biome([["rock","dirt","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","diamond","charcoal", "gold", "charcoal", "copper", "copper", "tin", "tin", "aluminum", "iron", "zinc", "lead", "nickel", "uranium"],["dirt","gravel","clay","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","mud"], ["dirt","dirt","dirt","gravel","dirt","dirt","dirt","dirt","dirt"]], [13, 32, 33], 1, ()=>{ + for(i = 0; i < width; i++){ + if(isEmpty(i, 40) && !outOfBounds(i, 40)){ + let elemsArr = ["tree", "grass", "dirt", "dirt", "dirt", "dirt", "dirt"], elem = elemsArr[Math.round(Math.random()*elemsArr.length)]; + if(elem == "tree"){ + let type = plants.tree[Math.round(Math.random()*plants.tree.length)]; + let elem = (elements[`${type}_seed`] == undefined) ? "apple_seed" : `${type}_seed`; + createPixel(elem, i, 40); + } else { + createPixel(elem, i, 40); + } + } + } + }); + } +} From b97f77ba7e712852ed307540f68df2902981c60b Mon Sep 17 00:00:00 2001 From: Alexthetransfem <124483815+theenchantedsword@users.noreply.github.com> Date: Tue, 1 Jul 2025 21:11:22 -0500 Subject: [PATCH 2/3] Update mod-list.html --- mod-list.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mod-list.html b/mod-list.html index cd5fcfa0..0141dd98 100644 --- a/mod-list.html +++ b/mod-list.html @@ -149,7 +149,6 @@ velocity.jsBeta for explosion velocity, and later wind, which may come to the base game in the futureR74n Tools & Settings -betaworldgen.jsAdvanced world generationAdora betterModManager.jsImprovements to the Mod Managerggod betterSettings.jsAdditional settings and functionalityggod betterStats.jsTrack actual running TPS of the simulationmollthecoder @@ -190,7 +189,8 @@ text.jsTools to write textRedBirdly texturepack.jsTools that let you create and share custom texture packsnousernamefound the_ground.jsSeveral rock types, worldgen settings, and gemstonesAlice - +worldgenlibrary.jsWorld generation libraryAdora + Science & Chemistry alcohol.jsMethanol, (iso-)propanol, and butanolAlice alkahest.jsThe alkahest, a liquid which dissolves anythingAlice @@ -451,6 +451,7 @@ structure_test.jsTest for implementing structures into SandboxelsAlice test.jsTest that adds mayo :)R74n tool_pixel_behavior.jsGives unique behaviors to tools if placed with cheatsAlice +worldgenlibrary.jsWorld generation libraryAdora worldgen_test.jsElement that generates a save with a grass layer, dirt layer, rock layer, and a pondAlice Broken or Deprecated From f713ea983f55ae4a5b2e698ccc7da9e71d8e624a Mon Sep 17 00:00:00 2001 From: slweeb <91897291+slweeb@users.noreply.github.com> Date: Tue, 1 Jul 2025 22:15:49 -0400 Subject: [PATCH 3/3] Rename worldgenlibrary.js to mods/worldgenlibrary.js --- worldgenlibrary.js => mods/worldgenlibrary.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename worldgenlibrary.js => mods/worldgenlibrary.js (100%) diff --git a/worldgenlibrary.js b/mods/worldgenlibrary.js similarity index 100% rename from worldgenlibrary.js rename to mods/worldgenlibrary.js