From 85c1e3ba9670e883dabee1ec79d4047c447a6143 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 31 Aug 2024 04:03:13 +0900 Subject: [PATCH] new world size and generator for Alpha 2 with backwards compatibility --- .../terrarum/TerrarumAppConfiguration.kt | 2 +- .../terrarum/modulebasegame/TerrarumIngame.kt | 13 +-- .../modulebasegame/worldgenerator/Biomegen.kt | 3 +- .../modulebasegame/worldgenerator/Cavegen.kt | 19 ++-- .../modulebasegame/worldgenerator/Oregen.kt | 4 +- .../modulebasegame/worldgenerator/Terragen.kt | 91 +++++++++++-------- .../modulebasegame/worldgenerator/Treegen.kt | 7 +- .../modulebasegame/worldgenerator/Worldgen.kt | 54 +++++++++-- .../terrarum/tests/WorldgenNoiseSandbox.kt | 37 ++++++-- 9 files changed, 156 insertions(+), 74 deletions(-) diff --git a/src/net/torvald/terrarum/TerrarumAppConfiguration.kt b/src/net/torvald/terrarum/TerrarumAppConfiguration.kt index 59bc9b8ce..4a9c5fe4e 100644 --- a/src/net/torvald/terrarum/TerrarumAppConfiguration.kt +++ b/src/net/torvald/terrarum/TerrarumAppConfiguration.kt @@ -69,7 +69,7 @@ basegame * e.g. 0x02010034 will be translated as 2.1.52 * */ - const val VERSION_RAW: Long = 0x0000_000004_000003 + const val VERSION_RAW: Long = 0x0000_000004_000004 // Commit counts up to the Release 0.3.0: 2259 // Commit counts up to the Release 0.3.1: 2278 // Commit counts up to the Release 0.3.2: 2732 diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index f9415f3cb..509550c3c 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -168,10 +168,11 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { // x: neither (this.hitbox.endX >= WorldCamera.x && this.hitbox.startX <= WorldCamera.xEnd)) - val SIZE_SMALL = Point2i(6030, 4500) - val SIZE_NORMAL = Point2i(9000, 6750) - val SIZE_LARGE = Point2i(13500, 10080) - val SIZE_HUGE = Point2i(22500, 16920) // world ratio: 4:3 + // Vchunks = (10 * Hchunks)^0.6, rounded towards nearest even number + val SIZE_SMALL = Point2i(CHUNK_W*67, CHUNK_H*50) + val SIZE_NORMAL = Point2i(CHUNK_W*100, CHUNK_H*64) + val SIZE_LARGE = Point2i(CHUNK_W*150, CHUNK_H*80) + val SIZE_HUGE = Point2i(CHUNK_W*250, CHUNK_H*110) // world ratio: 4:3 val NEW_WORLD_SIZE = arrayOf(SIZE_SMALL, SIZE_NORMAL, SIZE_LARGE, SIZE_HUGE) val WORLDPORTAL_NEW_WORLD_SIZE = arrayOf(SIZE_SMALL, SIZE_NORMAL, SIZE_LARGE, SIZE_HUGE) @@ -383,7 +384,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { // feed info to the worldgen - Worldgen.attachMap(world, WorldgenParams(world.generatorSeed)) + Worldgen.attachMap(world, WorldgenParams.getParamsByVersion(codices.worldGenver, world.generatorSeed)) } loadCallback = codices.callbackAfterLoad @@ -535,7 +536,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { //WorldGenerator.attachMap(world) //WorldGenerator.SEED = worldParams.worldGenSeed //WorldGenerator.generateMap() - Worldgen.attachMap(world, WorldgenParams(worldParams.worldGenSeed)) + Worldgen.attachMap(world, WorldgenParams.getParamsByVersion(null, worldParams.worldGenSeed)) Worldgen.generateMap(App.getLoadScreen()) diff --git a/src/net/torvald/terrarum/modulebasegame/worldgenerator/Biomegen.kt b/src/net/torvald/terrarum/modulebasegame/worldgenerator/Biomegen.kt index 29d88ceff..091e65883 100644 --- a/src/net/torvald/terrarum/modulebasegame/worldgenerator/Biomegen.kt +++ b/src/net/torvald/terrarum/modulebasegame/worldgenerator/Biomegen.kt @@ -2,7 +2,6 @@ package net.torvald.terrarum.modulebasegame.worldgenerator import com.sudoplay.joise.Joise import com.sudoplay.joise.module.* -import net.torvald.terrarum.App import net.torvald.terrarum.LoadScreenBase import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.gameitems.ItemID @@ -99,7 +98,7 @@ class Biomegen(world: GameWorld, isFinal: Boolean, seed: Long, params: Any, val val sx = sin(sampleTheta) * soff + soff // plus sampleOffset to make only val sz = cos(sampleTheta) * soff + soff // positive points are to be sampled for (y in yStart until yStart + CHUNK_H) { - val sy = y - (world.height - YHEIGHT_MAGIC) * YHEIGHT_DIVISOR // Q&D offsetting to make ratio of sky:ground to be constant + val sy = Worldgen.getSY(y) val control1 = noises[0].get(sx, sy, sz).coerceIn(0.0, 0.99999).times(slices).toInt().coerceAtMost(slices - 1) diff --git a/src/net/torvald/terrarum/modulebasegame/worldgenerator/Cavegen.kt b/src/net/torvald/terrarum/modulebasegame/worldgenerator/Cavegen.kt index 7cb06797a..2208c3ae0 100644 --- a/src/net/torvald/terrarum/modulebasegame/worldgenerator/Cavegen.kt +++ b/src/net/torvald/terrarum/modulebasegame/worldgenerator/Cavegen.kt @@ -2,7 +2,6 @@ package net.torvald.terrarum.modulebasegame.worldgenerator import com.sudoplay.joise.Joise import com.sudoplay.joise.module.* -import net.torvald.terrarum.App import net.torvald.terrarum.LoadScreenBase import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.gameworld.GameWorld @@ -16,11 +15,6 @@ import kotlin.math.sin */ class Cavegen(world: GameWorld, isFinal: Boolean, val highlandLowlandSelectCache: ModuleCache, seed: Long, params: Any) : Gen(world, isFinal, seed, params) { - companion object { - const val YHEIGHT_MAGIC = 2800.0 / 3.0 - const val YHEIGHT_DIVISOR = 2.0 / 7.0 - } - override fun getDone(loadscreen: LoadScreenBase?) { loadscreen?.let { it.stageValue += 1 @@ -41,7 +35,7 @@ class Cavegen(world: GameWorld, isFinal: Boolean, val highlandLowlandSelectCache for (y in yStart until yStart + CHUNK_H) { val sx = sin(st) * soff + soff // plus sampleOffset to make only val sz = cos(st) * soff + soff // positive points are to be sampled - val sy = y - (world.height - YHEIGHT_MAGIC) * YHEIGHT_DIVISOR // Q&D offsetting to make ratio of sky:ground to be constant + val sy = Worldgen.getSY(y) // DEBUG NOTE: it is the OFFSET FROM THE IDEAL VALUE (observed land height - (HEIGHT * DIVISOR)) that must be constant val noiseValue = noises.map { it.get(sx, sy, sz) } @@ -73,11 +67,18 @@ class Cavegen(world: GameWorld, isFinal: Boolean, val highlandLowlandSelectCache it.seed = seed shake caveMagic } - val caveAttenuateBias = ModuleCache().also {it.setSource(ModuleBias().also { + val caveAttenuateBias0 = ModuleCache().also {it.setSource(ModuleBias().also { it.setSource(highlandLowlandSelectCache) it.setBias(params.caveAttenuateBias) // (0.5+) adjust the "concentration" of the cave gen. Lower = larger voids })} + val caveAttenuateBias = caveAttenuateBias0.let { + ModuleScaleOffset().also { + it.setSource(caveAttenuateBias0) + it.setScale(params.caveAttenuateScale) + } + } + val caveShapeAttenuate = ModuleCombiner().also { it.setType(ModuleCombiner.CombinerType.MULT) it.setSource(0, caveShape) @@ -132,7 +133,7 @@ class Cavegen(world: GameWorld, isFinal: Boolean, val highlandLowlandSelectCache it.setLowSource(0.0) it.setHighSource(1.0) it.setControlSource(caveBlockageAttenuate) - it.setThreshold(params.caveBlockageSelectThre) // adjust cave cloing-up strength. Larger = more closing + it.setThreshold(params.caveBlockageSelectThre) // adjust cave cloing-up strength. Lower = more closing it.setFalloff(0.0) } diff --git a/src/net/torvald/terrarum/modulebasegame/worldgenerator/Oregen.kt b/src/net/torvald/terrarum/modulebasegame/worldgenerator/Oregen.kt index e7585d481..7fe8e1a43 100644 --- a/src/net/torvald/terrarum/modulebasegame/worldgenerator/Oregen.kt +++ b/src/net/torvald/terrarum/modulebasegame/worldgenerator/Oregen.kt @@ -4,8 +4,6 @@ import com.sudoplay.joise.Joise import com.sudoplay.joise.module.* import net.torvald.terrarum.* import net.torvald.terrarum.gameworld.GameWorld -import net.torvald.terrarum.modulebasegame.worldgenerator.Terragen.Companion.YHEIGHT_DIVISOR -import net.torvald.terrarum.modulebasegame.worldgenerator.Terragen.Companion.YHEIGHT_MAGIC import net.torvald.terrarum.realestate.LandUtil.CHUNK_H import net.torvald.terrarum.realestate.LandUtil.CHUNK_W import kotlin.math.cos @@ -46,7 +44,7 @@ class Oregen(world: GameWorld, isFinal: Boolean, private val caveAttenuateBiasSc for (y in yStart until yStart + CHUNK_H) { val sx = sin(st) * soff + soff // plus sampleOffset to make only val sz = cos(st) * soff + soff // positive points are to be sampled - val sy = y - (world.height - YHEIGHT_MAGIC) * YHEIGHT_DIVISOR // Q&D offsetting to make ratio of sky:ground to be constant + val sy = Worldgen.getSY(y) // DEBUG NOTE: it is the OFFSET FROM THE IDEAL VALUE (observed land height - (HEIGHT * DIVISOR)) that must be constant // get the actual noise values diff --git a/src/net/torvald/terrarum/modulebasegame/worldgenerator/Terragen.kt b/src/net/torvald/terrarum/modulebasegame/worldgenerator/Terragen.kt index 08ef04e55..4a5f2bf45 100644 --- a/src/net/torvald/terrarum/modulebasegame/worldgenerator/Terragen.kt +++ b/src/net/torvald/terrarum/modulebasegame/worldgenerator/Terragen.kt @@ -3,13 +3,10 @@ package net.torvald.terrarum.modulebasegame.worldgenerator import com.sudoplay.joise.Joise import com.sudoplay.joise.module.* import net.torvald.random.HQRNG -import net.torvald.random.XXHash32 -import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.LoadScreenBase import net.torvald.terrarum.blockproperties.Block -import net.torvald.terrarum.concurrent.sliceEvenly import net.torvald.terrarum.gameworld.GameWorld -import net.torvald.terrarum.realestate.LandUtil +import net.torvald.terrarum.modulebasegame.worldgenerator.Worldgen.getClampedHeight import net.torvald.terrarum.realestate.LandUtil.CHUNK_H import net.torvald.terrarum.realestate.LandUtil.CHUNK_W import kotlin.math.cos @@ -21,11 +18,6 @@ import kotlin.math.sin */ class Terragen(world: GameWorld, isFinal: Boolean , val highlandLowlandSelectCache: ModuleCache, seed: Long, params: Any) : Gen(world, isFinal, seed, params) { - companion object { - const val YHEIGHT_MAGIC = 2800.0 / 3.0 - const val YHEIGHT_DIVISOR = 2.0 / 7.0 - } - private val dirtStoneDitherSize = 3 // actual dither size will be double of this value private val stoneSlateDitherSize = 4 @@ -52,8 +44,8 @@ class Terragen(world: GameWorld, isFinal: Boolean , val highlandLowlandSelectCac return tiers.lastIndex } - private val terragenYscaling = (world.height / 2400.0).pow(0.75) - private val terragenTiers = listOf(.0, .5, 1.0, 2.5).map { it * terragenYscaling } // pow 1.0 for 1-to-1 scaling; 0.75 is used to make deep-rock layers actually deep for huge world size + private val terragenYscaling = (world.getClampedHeight() / 2400.0).pow(0.75) + private val terragenTiers = (params as TerragenParams).terragenTiers.map { it * terragenYscaling } // pow 1.0 for 1-to-1 scaling; 0.75 is used to make deep-rock layers actually deep for huge world size //private fun draw(x: Int, y: Int, width: Int, height: Int, noiseValue: List, world: GameWorld) { override fun draw(xStart: Int, yStart: Int, noises: List, soff: Double) { @@ -66,7 +58,7 @@ class Terragen(world: GameWorld, isFinal: Boolean , val highlandLowlandSelectCac for (y in yStart until yStart + CHUNK_H) { val sx = sin(st) * soff + soff // plus sampleOffset to make only val sz = cos(st) * soff + soff // positive points are to be sampled - val sy = y - (world.height - YHEIGHT_MAGIC) * YHEIGHT_DIVISOR // Q&D offsetting to make ratio of sky:ground to be constant + val sy = Worldgen.getSY(y) // DEBUG NOTE: it is the OFFSET FROM THE IDEAL VALUE (observed land height - (HEIGHT * DIVISOR)) that must be constant val noiseValue = noises.map { it.get(sx, sy, sz) } @@ -177,7 +169,7 @@ class Terragen(world: GameWorld, isFinal: Boolean , val highlandLowlandSelectCac Joise(groundScaling), Joise(generateRockLayer(groundScaling, seed, params, (0..7).map { - thicknesses[it] + marblerng.nextTriangularBal() * 0.006 to (2.6 * terragenYscaling) + it * 0.18 + marblerng.nextTriangularBal() * 0.09 + thicknesses[it] + marblerng.nextTriangularBal() * 0.006 to (1.04 * params.terragenTiers[3] * terragenYscaling) + it * 0.18 + marblerng.nextTriangularBal() * 0.09 })), ) } @@ -248,33 +240,58 @@ class Terragen(world: GameWorld, isFinal: Boolean , val highlandLowlandSelectCac } } -data class TerragenParams( - val featureSize: Double = 333.0, - val lowlandScaleOffset: Double = -0.65, // linearly alters the height - val highlandScaleOffset: Double = -0.2, // linearly alters the height - val mountainScaleOffset: Double = -0.1, // linearly alters the height - val mountainDisturbance: Double = 0.7, // greater = more distortion, overhangs +interface TerragenParams { + val terragenTiers: List + val featureSize: Double + val lowlandScaleOffset: Double // linearly alters the height + val highlandScaleOffset: Double // linearly alters the height + val mountainScaleOffset: Double // linearly alters the height + val mountainDisturbance: Double // greater = more distortion, overhangs + val caveShapeFreq: Double //adjust the "density" of the caves + val caveAttenuateScale: Double // used with the caveAttenuateBias, controls the "concentration" of the cave gen + val caveAttenuateBias: Double // 1.0: flattens the gradient (deep voids are less tend to be larger). Also controls the distribution of ores. Equation: x^(log(bias) / log(0.5)) + val caveSelectThre: Double // also adjust this if you've touched the bias value. Number can be greater than 1.0 + val caveBlockageFractalFreq: Double + val caveBlockageSelectThre: Double // adjust cave closing-up strength. Lower = more closing + val rockBandCutoffFreq: Double +} - val caveShapeFreq: Double = 4.0, //adjust the "density" of the caves - val caveAttenuateBias: Double = 0.90, // adjust the "concentration" of the cave gen. Lower = larger voids - val caveSelectThre: Double = 0.918, // also adjust this if you've touched the bias value. Number can be greater than 1.0 - val caveBlockageFractalFreq: Double = 8.88, - val caveBlockageSelectThre: Double = 1.40, // adjust cave cloing-up strength. Larger = more closing +data class TerragenParamsAlpha1( + override val terragenTiers: List = listOf(.0, .5, 1.0, 2.5), - val rockBandCutoffFreq: Double = 4.0, + override val featureSize: Double = 333.0, + override val lowlandScaleOffset: Double = -0.65, // linearly alters the height + override val highlandScaleOffset: Double = -0.2, // linearly alters the height + override val mountainScaleOffset: Double = -0.1, // linearly alters the height + override val mountainDisturbance: Double = 0.7, // greater = more distortion, overhangs -// val oreCopperFreq: Double = 0.024, // adjust the "density" of the ore veins -// val oreCopperPower: Double = 0.01, // super-low value almost negates the depth element -// val oreCopperScale: Double = 0.505, + override val caveShapeFreq: Double = 4.0, //adjust the "density" of the caves + override val caveAttenuateScale: Double = 1.0, // used with the caveAttenuateBias, controls the "concentration" of the cave gen + override val caveAttenuateBias: Double = 0.90, // 1.0: flattens the gradient (deep voids are less tend to be larger). Also controls the distribution of ores. Equation: x^(log(bias) / log(0.5)) + override val caveSelectThre: Double = 0.918, // also adjust this if you've touched the bias value. Number can be greater than 1.0 + override val caveBlockageFractalFreq: Double = 8.88, + override val caveBlockageSelectThre: Double = 1.40, // adjust cave closing-up strength. Lower = more closing -// val oreIronFreq: Double = 0.04, // adjust the "density" of the ore veins -// val oreIronPower: Double = 0.01, // super-low value almost negates the depth element -// val oreIronScale: Double = 0.505, + override val rockBandCutoffFreq: Double = 4.0, - // 0.01 - 0.505 - // 0.1 - 0.5 - // ... - // 0.8 - 0.42 -) { -} \ No newline at end of file +) : TerragenParams + +data class TerragenParamsAlpha2( + override val terragenTiers: List = listOf(.0, .5, 1.5, 3.75), + + override val featureSize: Double = 333.0, + override val lowlandScaleOffset: Double = -0.65, // linearly alters the height + override val highlandScaleOffset: Double = -0.2, // linearly alters the height + override val mountainScaleOffset: Double = -0.1, // linearly alters the height + override val mountainDisturbance: Double = 0.7, // greater = more distortion, overhangs + + override val caveShapeFreq: Double = 4.0, //adjust the "density" of the caves + override val caveAttenuateScale: Double = 0.98, // used with the caveAttenuateBias, controls the "concentration" of the cave gen + override val caveAttenuateBias: Double = 0.93, // 1.0: flattens the gradient (deep voids are less tend to be larger). Also controls the distribution of ores. Equation: x^(log(bias) / log(0.5)) + override val caveSelectThre: Double = 0.918, // also adjust this if you've touched the bias value. Number can be greater than 1.0 + override val caveBlockageFractalFreq: Double = 8.88, + override val caveBlockageSelectThre: Double = 1.40, // adjust cave closing-up strength. Lower = more closing + + override val rockBandCutoffFreq: Double = 4.0, +) : TerragenParams \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/worldgenerator/Treegen.kt b/src/net/torvald/terrarum/modulebasegame/worldgenerator/Treegen.kt index f0ec9bfee..1c7d30b7d 100644 --- a/src/net/torvald/terrarum/modulebasegame/worldgenerator/Treegen.kt +++ b/src/net/torvald/terrarum/modulebasegame/worldgenerator/Treegen.kt @@ -8,7 +8,8 @@ import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.gameworld.BlockAddress import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.modulebasegame.TerrarumIngame -import net.torvald.terrarum.modulebasegame.worldgenerator.Terragen.Companion.YHEIGHT_DIVISOR +import net.torvald.terrarum.modulebasegame.worldgenerator.Worldgen.YHEIGHT_DIVISOR +import net.torvald.terrarum.modulebasegame.worldgenerator.Worldgen.getClampedHeight import net.torvald.terrarum.realestate.LandUtil import net.torvald.terrarum.serialise.toUint @@ -43,11 +44,11 @@ class Treegen(world: GameWorld, isFinal: Boolean, seed: Long, val terragenParams private fun makeGrassMap(xs: IntProgression): Array> { val r = Array>(xs.last - xs.first + 1) { emptyList() } - val ymax = (world.height * YHEIGHT_DIVISOR + terragenParams.featureSize).ceilToInt() + val ymax = (world.getClampedHeight() * YHEIGHT_DIVISOR + terragenParams.featureSize).ceilToInt() for (x in xs) { val ys = ArrayList() - var y = (world.height * YHEIGHT_DIVISOR - terragenParams.featureSize).floorToInt().coerceAtLeast(1) + var y = (world.getClampedHeight() * YHEIGHT_DIVISOR - terragenParams.featureSize).floorToInt().coerceAtLeast(1) var tileUp = world.getTileFromTerrain(x, y - 1) var tile = world.getTileFromTerrain(x, y) while (y < ymax) { diff --git a/src/net/torvald/terrarum/modulebasegame/worldgenerator/Worldgen.kt b/src/net/torvald/terrarum/modulebasegame/worldgenerator/Worldgen.kt index a06d7143a..66b211df9 100644 --- a/src/net/torvald/terrarum/modulebasegame/worldgenerator/Worldgen.kt +++ b/src/net/torvald/terrarum/modulebasegame/worldgenerator/Worldgen.kt @@ -27,6 +27,24 @@ import kotlin.math.roundToLong */ object Worldgen { + const val YHEIGHT_MAGIC = 2800.0 / 3.0 + const val YHEIGHT_DIVISOR = 2.0 / 7.0 + + private const val ALPHA_1_2 = 0x0000_000004_000002 + + fun GameWorld.getClampedHeight(): Int { + val clampNum = when (INGAME.worldGenVer) { + in 0L..ALPHA_1_2 -> 4500 // 4500 is the height on the HUGE setting until Alpha 1.2 + else -> 3200 + } + return this.height.coerceAtMost(clampNum) + } + + + /** Will modify the Terragen as if the height of the world is strictly 3200 (see [GameWorld.getClampedHeight]) */ + fun getSY(y: Int): Double = y - (world.getClampedHeight() - YHEIGHT_MAGIC) * YHEIGHT_DIVISOR // Q&D offsetting to make ratio of sky:ground to be constant + + private lateinit var world: GameWorld lateinit var params: WorldgenParams private set @@ -164,7 +182,7 @@ object Worldgen { * @return starting chunk Y index, ending chunk Y index (inclusive) */ fun getChunkGenStrip(world: GameWorld): Pair { - val start = (0.00342f * world.height - 3.22f).floorToInt().coerceAtLeast(1) + val start = (0.00342f * world.getClampedHeight() - 3.22f).floorToInt().coerceAtLeast(1) // this value has to extend up, otherwise the player may spawn into the chopped-off mountaintop // this value has to extend down into the rock layer, otherwise, if the bottom of the bottom chunk is dirt, they will turn into grasses // - the second condition is nullified with the new NOT-GENERATED markers on the terrain @@ -408,11 +426,18 @@ object Worldgen { } private fun getCaveAttenuateBiasScaled(highlandLowlandSelectCache: ModuleCache, params: TerragenParams): ModuleCache { - val caveAttenuateBias = ModuleBias().also { + val caveAttenuateBias0 = ModuleBias().also { it.setSource(highlandLowlandSelectCache) it.setBias(params.caveAttenuateBias) // (0.5+) adjust the "concentration" of the cave gen. Lower = larger voids } + val caveAttenuateBias = caveAttenuateBias0.let { + ModuleScaleOffset().also { + it.setSource(caveAttenuateBias0) + it.setScale(params.caveAttenuateScale) + } + } + val scale = ModuleScaleDomain().also { it.setScaleX(1.0 / params.featureSize) // adjust this value to change features size it.setScaleY(1.0 / params.featureSize) @@ -461,12 +486,29 @@ abstract class Gen(val world: GameWorld, val isFinal: Boolean, val seed: Long, v } } -data class WorldgenParams( +sealed class WorldgenParams( val seed: Long, // optional parameters - val terragenParams: TerragenParams = TerragenParams(), - val biomegenParams: BiomegenParams = BiomegenParams(), - val treegenParams: TreegenParams = TreegenParams(), + val terragenParams: TerragenParams, + val biomegenParams: BiomegenParams, + val treegenParams: TreegenParams, +) { + companion object { + fun getParamsByVersion(versionRaw: Long?, seed: Long): WorldgenParams { + val versionRaw = versionRaw ?: 0x7FFF_FFFFFF_FFFFFF // use current version for null + when (versionRaw) { + in 0..0x0000_000004_000003 -> return WorldgenParamsAlpha1(seed) // 0.4.3 is a dev-only version + in 0x0000_000004_000004..0x7FFF_FFFFFF_FFFFFF -> return WorldgenParamsAlpha2(seed) // 0.4.4 is also a dev-only version + else -> throw IllegalArgumentException("Unknown version: $versionRaw") + } + } + } +} +class WorldgenParamsAlpha1(seed: Long) : WorldgenParams( + seed, TerragenParamsAlpha1(), BiomegenParams(), TreegenParams(), +) +class WorldgenParamsAlpha2(seed: Long) : WorldgenParams( + seed, TerragenParamsAlpha2(), BiomegenParams(), TreegenParams(), ) infix fun Long.shake(other: Long): Long { diff --git a/src/net/torvald/terrarum/tests/WorldgenNoiseSandbox.kt b/src/net/torvald/terrarum/tests/WorldgenNoiseSandbox.kt index 83cac9641..b97c4603c 100644 --- a/src/net/torvald/terrarum/tests/WorldgenNoiseSandbox.kt +++ b/src/net/torvald/terrarum/tests/WorldgenNoiseSandbox.kt @@ -24,14 +24,14 @@ import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.concurrent.RunnableFun import net.torvald.terrarum.concurrent.ThreadExecutor import net.torvald.terrarum.concurrent.sliceEvenly -import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.worldgenerator.* import net.torvald.terrarum.worlddrawer.toRGBA import net.torvald.terrarumsansbitmap.gdx.TerrarumSansBitmap import java.util.concurrent.Future import kotlin.math.* import kotlin.random.Random -import net.torvald.terrarum.modulebasegame.worldgenerator.Terragen +import net.torvald.terrarum.modulebasegame.worldgenerator.Worldgen.YHEIGHT_DIVISOR +import net.torvald.terrarum.modulebasegame.worldgenerator.Worldgen.YHEIGHT_MAGIC import java.io.PrintStream const val NOISEBOX_WIDTH = 1200 @@ -81,7 +81,7 @@ class WorldgenNoiseSandbox : ApplicationAdapter() { private var generationTime = 0f - private val NM_TERR = TerragenTest to TerragenParams() + private val NM_TERR = TerragenTest to TerragenParamsAlpha2() private val NM_BIOME = BiomeMaker to BiomegenParams() private val NOISEMAKER = NM_TERR @@ -164,6 +164,23 @@ class WorldgenNoiseSandbox : ApplicationAdapter() { } } + + fun getClampedHeight(): Int { + return 3200 + } + + private fun Int.addSY(): Int { + val offset = 90 * 8 + return this + offset + } + + private fun Int.subtractSY(): Int { + val offset = 90 * 8 + return this - offset + } + + private fun getSY(y: Int): Double = y - (getClampedHeight() - YHEIGHT_MAGIC) * YHEIGHT_DIVISOR // Q&D offsetting to make ratio of sky:ground to be constant + private fun renderNoise(noiseMaker: Pair, callback: () -> Unit = {}) { generationStartTime = System.nanoTime() @@ -187,8 +204,7 @@ class WorldgenNoiseSandbox : ApplicationAdapter() { sin(sampleTheta) * sampleOffset + sampleOffset // plus sampleOffset to make only val sampleZ = cos(sampleTheta) * sampleOffset + sampleOffset // positive points are to be sampled - val sampleY = - y - (NOISEBOX_HEIGHT - Terragen.YHEIGHT_MAGIC) * Terragen.YHEIGHT_DIVISOR // Q&D offsetting to make ratio of sky:ground to be constant + val sampleY = getSY(y) noiseMaker.first.draw(x, y, localJoise.mapIndexed { index, it -> it.get(sampleX, sampleY, sampleZ) @@ -350,7 +366,7 @@ internal object TerragenTest : NoiseMaker { ) private val terragenYscaling = (NOISEBOX_HEIGHT / 2400.0).pow(0.75) - private val terragenTiers = listOf(.0, .5, 1.0, 2.5).map { it * terragenYscaling } // pow 1.0 for 1-to-1 scaling; 0.75 is used to make deep-rock layers actually deep for huge world size + private val terragenTiers = listOf(.0, .5, 1.5, 4.0).map { it * terragenYscaling } // pow 1.0 for 1-to-1 scaling; 0.75 is used to make deep-rock layers actually deep for huge world size override fun draw(x: Int, y: Int, noiseValue: List, outTex: Pixmap) { val terr = noiseValue[0].tiered(terragenTiers) @@ -564,11 +580,18 @@ internal object TerragenTest : NoiseMaker { it.seed = seed shake caveMagic } - val caveAttenuateBias = ModuleCache().also { it.setSource(ModuleBias().also { + val caveAttenuateBias0 = ModuleCache().also { it.setSource(ModuleBias().also { it.setSource(highlandLowlandSelectCache) it.setBias(params.caveAttenuateBias) // (0.5+) adjust the "concentration" of the cave gen. Lower = larger voids })} + val caveAttenuateBias = caveAttenuateBias0.let { + ModuleScaleOffset().also { + it.setSource(caveAttenuateBias0) + it.setScale(params.caveAttenuateScale) + } + } + val caveShapeAttenuate = ModuleCombiner().also { it.setType(ModuleCombiner.CombinerType.MULT) it.setSource(0, caveShape)