Class WorldMapGenerator
java.lang.Object
com.github.yellowstonegames.world.WorldMapGenerator
- Direct Known Subclasses:
DiagonalWorldMap, EllipticalWorldMap, GlobeMap, HexagonalWorldMap, HyperellipticalWorldMap, LatLonWorldMap, LocalMap, RotatingGlobeMap, RoundSideWorldMap, StretchWorldMap, TilingWorldMap
Can be used to generate world maps with a wide variety of data, starting with height, temperature and moisture.
To generate maps, this uses two
There's lots of implementations here for different usage. The maps this produces with
This interacts closely with
long variables for its state, and if you use the same kind of Noise
configuration with the same state, you will get the same world as a result. Calling
generate(float, float, long, long) also allows setting the land modifier and heat modifier to make worlds
that have more or less ocean vs. land and/or ice vs. desert.
There's lots of implementations here for different usage. The maps this produces with
StretchWorldMap are
valid for stretching around spheres, while the maps from TilingWorldMap are for toroidal world projections
and will wrap from edge to opposite edge seamlessly thanks to
a technique from the Accidental Noise
Library that involves getting a 2D slice of 4D continuous noise, such as Simplex. Because of how continuous noise
works, this also allows extremely high zoom levels for all types of map as long as certain parameters are within
reason. Other world maps produce more conventional shapes; GlobeMap and RotatingGlobeMap make a
view of a marble-like world from space, and others make more unconventional shapes, like EllipticalWorldMap,
which forms a 2:1 ellipse shape that accurately keeps sizes but not relative shapes, RoundSideWorldMap, which
forms a pill-shape, and HyperellipticalWorldMap, which takes parameters so it can fit
any shape between a circle or ellipse and a rectangle (the default is a slightly squared-off ellipse). You can access
the height map with the heightData field, the heat map with the heatData field, the moisture map
with the moistureData field, and a special map that stores ints representing the codes for various ranges of
elevation (0 to 8 inclusive, with 0 the deepest ocean and 8 the highest mountains) with heightCodeData. The
last map should be noted as being the simplest way to find what is land and what is water; any height code 4 or
greater is land, and any height code 3 or less is water.
This interacts closely with
BiomeMapper, and BiomeMapper can't create a map of what types of ecosystem are
present without first having a world generated by a WorldMapGenerator.-
Field Summary
FieldsModifier and TypeFieldDescriptionlonglongprotected floatstatic final floatstatic final floatstatic final floatstatic final floatstatic final com.github.yellowstonegames.grid.NoiseA Noise that has a higher frequency than that class defaults to, which is useful for maps here.static final floatstatic final floatstatic final floatstatic final floatfinal float[][]floatfinal intfinal int[][]final float[][]final com.github.yellowstonegames.grid.Regionfloatfloatfloatfloatstatic final floatstatic final floatfloatfloatfloatfinal float[][]com.github.tommyettinger.random.FlowRandomstatic final floatstatic final floatstatic final floatstatic final floatlonglongstatic final floatstatic final floatstatic final floatstatic final floatprotected com.github.tommyettinger.ds.IntListprotected com.github.tommyettinger.ds.IntListintintintintfinal intintprotected intprotected int -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedConstructs a WorldMapGenerator (this class is abstract, so you should typically call this from a subclass or as part of an anonymous class that implementsregenerate(int, int, int, int, float, float, long, long)).protectedWorldMapGenerator(int mapWidth, int mapHeight) Constructs a WorldMapGenerator (this class is abstract, so you should typically call this from a subclass or as part of an anonymous class that implementsregenerate(int, int, int, int, float, float, long, long)).protectedWorldMapGenerator(long initialSeed, int mapWidth, int mapHeight) Constructs a WorldMapGenerator (this class is abstract, so you should typically call this from a subclass or as part of an anonymous class that implementsregenerate(int, int, int, int, float, float, long, long)).protectedUsed to implement most of the copy constructor for subclasses; this cannot copy Noise implementations and leaves that up to the subclass, but will copy all non-static fields defined in WorldMapGenerator from other. -
Method Summary
Modifier and TypeMethodDescriptionintcodeHeight(float high) voidgenerate()Generates a world using a random RNG state and all parameters randomized.voidgenerate(float landMod, float heatMod, long stateA, long stateB) Generates a world using the specified RNG state as a long, with specific land and heat modifiers that affect the land-water ratio and the average temperature, respectively.voidgenerate(long stateA, long stateB) Generates a world using the specified RNG state as a long.floatGets the longitude line the map is centered on, which should usually be between 0 and 2 * PI.com.github.yellowstonegames.grid.Coordproject(float latitude, float longitude) Given a latitude and longitude in radians (the conventional way of describing points on a globe), this gets the (x,y) Coord on the map projection this generator uses that corresponds to the given lat-lon coordinates.protected abstract voidregenerate(int startX, int startY, int usedWidth, int usedHeight, float landMod, float heatMod, long stateA, long stateB) protected static floatremoveExcess(float radians) voidsetCenterLongitude(float centerLongitude) Sets the center longitude line to a longitude measured in radians, from 0 to 2 * PI.Serializes this generator's entire state to a String; it should be readable when creating a new instance of this type with a constructor taking(int, int, String)or (preferably)recreateFromString(String).intwrapX(int x, int y) intwrapY(int x, int y) voidzoomIn()Floats the resolution of the map and halves the area it covers; the 2D arrays this uses keep their sizes.voidzoomIn(int zoomAmount, int zoomCenterX, int zoomCenterY) Floats the resolution of the map and halves the area it covers repeatedly, doublingzoomAmounttimes; the 2D arrays this uses keep their sizes.voidzoomOut()Halves the resolution of the map and floats the area it covers; the 2D arrays this uses keep their sizes.voidzoomOut(int zoomAmount, int zoomCenterX, int zoomCenterY) Halves the resolution of the map and floats the area it covers repeatedly, halvingzoomAmounttimes; the 2D arrays this uses keep their sizes.
-
Field Details
-
width
public final int width -
height
public final int height -
seedA
public long seedA -
seedB
public long seedB -
cacheA
public long cacheA -
cacheB
public long cacheB -
rng
public com.github.tommyettinger.random.FlowRandom rng -
heightData
public final float[][] heightData -
heatData
public final float[][] heatData -
moistureData
public final float[][] moistureData -
landData
public final com.github.yellowstonegames.grid.Region landData -
heightCodeData
public final int[][] heightCodeData -
landModifier
public float landModifier -
heatModifier
public float heatModifier -
minHeight
public float minHeight -
maxHeight
public float maxHeight -
minHeat
public float minHeat -
maxHeat
public float maxHeat -
minWet
public float minWet -
maxWet
public float maxWet -
centerLongitude
protected float centerLongitude -
zoom
public int zoom -
startX
public int startX -
startY
public int startY -
usedWidth
public int usedWidth -
usedHeight
public int usedHeight -
startCacheX
protected com.github.tommyettinger.ds.IntList startCacheX -
startCacheY
protected com.github.tommyettinger.ds.IntList startCacheY -
zoomStartX
protected int zoomStartX -
zoomStartY
protected int zoomStartY -
DEFAULT_NOISE
public static final com.github.yellowstonegames.grid.Noise DEFAULT_NOISEA Noise that has a higher frequency than that class defaults to, which is useful for maps here. With the default Noise frequency of 1f/32f, the maps this produces are giant blurs. This defaults to using Honey noise with 1.0f frequency and only one octave (each subclass will probably need more octaves).
Even though this is a Noise and so technically can be edited, that seems to have issues when there's more than one WorldMapGenerator that uses this field. So you can feel free to use this as a Noise when generators need one, but don't change it too much, if at all. -
deepWaterLower
public static final float deepWaterLower- See Also:
-
deepWaterUpper
public static final float deepWaterUpper- See Also:
-
mediumWaterLower
public static final float mediumWaterLower- See Also:
-
mediumWaterUpper
public static final float mediumWaterUpper- See Also:
-
shallowWaterLower
public static final float shallowWaterLower- See Also:
-
shallowWaterUpper
public static final float shallowWaterUpper- See Also:
-
coastalWaterLower
public static final float coastalWaterLower- See Also:
-
coastalWaterUpper
public static final float coastalWaterUpper- See Also:
-
sandLower
public static final float sandLower- See Also:
-
sandUpper
public static final float sandUpper- See Also:
-
grassLower
public static final float grassLower- See Also:
-
grassUpper
public static final float grassUpper- See Also:
-
forestLower
public static final float forestLower- See Also:
-
forestUpper
public static final float forestUpper- See Also:
-
rockLower
public static final float rockLower- See Also:
-
rockUpper
public static final float rockUpper- See Also:
-
snowLower
public static final float snowLower- See Also:
-
snowUpper
public static final float snowUpper- See Also:
-
-
Constructor Details
-
WorldMapGenerator
Used to implement most of the copy constructor for subclasses; this cannot copy Noise implementations and leaves that up to the subclass, but will copy all non-static fields defined in WorldMapGenerator from other.- Parameters:
other- a WorldMapGenerator (subclass) to copy fields from
-
WorldMapGenerator
protected WorldMapGenerator()Constructs a WorldMapGenerator (this class is abstract, so you should typically call this from a subclass or as part of an anonymous class that implementsregenerate(int, int, int, int, float, float, long, long)). Always makes a 256x256 map. If you were usingWorldMapGenerator(long, int, int), then this would be the same as passing the parameters0x1337BABE1337D00DL, 256, 256. -
WorldMapGenerator
protected WorldMapGenerator(int mapWidth, int mapHeight) Constructs a WorldMapGenerator (this class is abstract, so you should typically call this from a subclass or as part of an anonymous class that implementsregenerate(int, int, int, int, float, float, long, long)). Takes only the width/height of the map. The initial seed is set to the same large long every time, and it's likely that you would set the seed when you callgenerate(long, long). The width and height of the map cannot be changed after the fact, but you can zoom in.- Parameters:
mapWidth- the width of the map(s) to generate; cannot be changed latermapHeight- the height of the map(s) to generate; cannot be changed later
-
WorldMapGenerator
protected WorldMapGenerator(long initialSeed, int mapWidth, int mapHeight) Constructs a WorldMapGenerator (this class is abstract, so you should typically call this from a subclass or as part of an anonymous class that implementsregenerate(int, int, int, int, float, float, long, long)). Takes an initial seed and the width/height of the map. TheinitialSeedparameter may or may not be used, since you can specify the seed to use when you callgenerate(long, long). The width and height of the map cannot be changed after the fact, but you can zoom in.- Parameters:
initialSeed- the seed for the FlowRandom this uses; this may also be set per-call to generatemapWidth- the width of the map(s) to generate; cannot be changed latermapHeight- the height of the map(s) to generate; cannot be changed later
-
-
Method Details
-
getCenterLongitude
public float getCenterLongitude()Gets the longitude line the map is centered on, which should usually be between 0 and 2 * PI.- Returns:
- the longitude line the map is centered on, in radians from 0 to 2 * PI
-
setCenterLongitude
public void setCenterLongitude(float centerLongitude) Sets the center longitude line to a longitude measured in radians, from 0 to 2 * PI. Positive arguments will be corrected with modulo, but negative ones may not always act as expected, and are strongly discouraged.- Parameters:
centerLongitude- the longitude to center the map projection on, from 0 to 2 * PI (can be any non-negative float).
-
removeExcess
protected static float removeExcess(float radians) -
generate
public void generate()Generates a world using a random RNG state and all parameters randomized. The worlds this produces will always have width and height as specified in the constructor (default 256x256). You can callzoomIn(int, int, int)to float the resolution and center on the specified area, but the width and height of the 2D arrays this changed, such asheightDataandmoistureDatawill be the same. -
generate
public void generate(long stateA, long stateB) Generates a world using the specified RNG state as a long. Other parameters will be randomized, using the same RNG state to start with. The worlds this produces will always have width and height as specified in the constructor (default 256x256). You can callzoomIn(int, int, int)to float the resolution and center on the specified area, but the width and height of the 2D arrays this changed, such asheightDataandmoistureDatawill be the same.- Parameters:
stateA- the first part of state to give this generator's RNG; if the whole state is the same as the last call, this will reuse datastateB- the second part of state to give this generator's RNG; if the whole state is the same as the last call, this will reuse data
-
generate
public void generate(float landMod, float heatMod, long stateA, long stateB) Generates a world using the specified RNG state as a long, with specific land and heat modifiers that affect the land-water ratio and the average temperature, respectively. The worlds this produces will always have width and height as specified in the constructor (default 256x256). You can callzoomIn(int, int, int)to float the resolution and center on the specified area, but the width and height of the 2D arrays this changed, such asheightDataandmoistureDatawill be the same.- Parameters:
landMod- 1f is Earth-like, less than 1 is more-water, more than 1 is more-land; a random value will be used if this is negativeheatMod- 1.125f is Earth-like, less than 1 is cooler, more than 1 is hotter; a random value will be used if this is negativestateA- the first part of state to give this generator's RNG; if the whole state is the same as the last call, this will reuse datastateB- the second part of state to give this generator's RNG; if the whole state is the same as the last call, this will reuse data
-
zoomOut
public void zoomOut()Halves the resolution of the map and floats the area it covers; the 2D arrays this uses keep their sizes. This version of zoomOut always zooms out from the center of the currently used area.
Only has an effect if you have previously zoomed in usingzoomIn(int, int, int)or its overload. -
zoomOut
public void zoomOut(int zoomAmount, int zoomCenterX, int zoomCenterY) Halves the resolution of the map and floats the area it covers repeatedly, halvingzoomAmounttimes; the 2D arrays this uses keep their sizes. This version of zoomOut allows you to specify where the zoom should be centered, using the current coordinates (if the map size is 256x256, then coordinates should be between 0 and 255, and will refer to the currently used area and not necessarily the full world size).
Only has an effect if you have previously zoomed in usingzoomIn(int, int, int)or its overload.- Parameters:
zoomCenterX- the center X position to zoom out from; if too close to an edge, this will stop moving before it would extend past an edgezoomCenterY- the center Y position to zoom out from; if too close to an edge, this will stop moving before it would extend past an edge
-
zoomIn
public void zoomIn()Floats the resolution of the map and halves the area it covers; the 2D arrays this uses keep their sizes. This version of zoomIn always zooms in to the center of the currently used area.
Although there is no technical restriction on maximum zoom, zooming in more than 5 times (64x scale or greater) will make the map appear somewhat less realistic due to rounded shapes appearing more bubble-like and less like a normal landscape. -
zoomIn
public void zoomIn(int zoomAmount, int zoomCenterX, int zoomCenterY) Floats the resolution of the map and halves the area it covers repeatedly, doublingzoomAmounttimes; the 2D arrays this uses keep their sizes. This version of zoomIn allows you to specify where the zoom should be centered, using the current coordinates (if the map size is 256x256, then coordinates should be between 0 and 255, and will refer to the currently used area and not necessarily the full world size).
Although there is no technical restriction on maximum zoom, zooming in more than 5 times (64x scale or greater) will make the map appear somewhat less realistic due to rounded shapes appearing more bubble-like and less like a normal landscape.- Parameters:
zoomCenterX- the center X position to zoom in to; if too close to an edge, this will stop moving before it would extend past an edgezoomCenterY- the center Y position to zoom in to; if too close to an edge, this will stop moving before it would extend past an edge
-
regenerate
protected abstract void regenerate(int startX, int startY, int usedWidth, int usedHeight, float landMod, float heatMod, long stateA, long stateB) -
project
public com.github.yellowstonegames.grid.Coord project(float latitude, float longitude) Given a latitude and longitude in radians (the conventional way of describing points on a globe), this gets the (x,y) Coord on the map projection this generator uses that corresponds to the given lat-lon coordinates. If this generator does not represent a globe (if it is toroidal, for instance) or if there is no "good way" to calculate the projection for a given lat-lon coordinate, this returns null. The default implementation always returns null. If this is a supported operation and the parameters are valid, this returns a Coord with x between 0 andwidth, and y between 0 andheight, both exclusive. Automatically wraps the Coord's values usingwrapX(int, int)andwrapY(int, int). -
codeHeight
public int codeHeight(float high) -
wrapX
public int wrapX(int x, int y) -
wrapY
public int wrapY(int x, int y) -
stringSerialize
Serializes this generator's entire state to a String; it should be readable when creating a new instance of this type with a constructor taking(int, int, String)or (preferably)recreateFromString(String). The constructor typically takes width, height, and a String produced by this method. recreateFromString() typically takes just the String produced by this method.
Every existing implementation of this method puts each field on a new line, separated by `\n`, with width first and height second. This allows recreateFromString() to safely read in the first two lines to get the needed width and height for the constructor, and then can just call that and return the new generator. The constructor needs height and width to call a super-constructor that correctly sizes all the internal arrays,WorldMapGenerator(int, int).- Returns:
- a String that stores the entire state of this generator
-