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 @@