World Generation
KubeJS TFC allows users to easily build some of TFC’s world generation features
In the tfc.worldgen.data
event there are methods for:
Have a look through some examples at the bottom of the page
Additionally, there is a new startup event tfc.rock_settings.register
which is used to add, remove, and modify rock layers in TFC’s default world generation, the methods can be found here
Adding Features
Much of TFC’s world generation configuration is done through tags. In the tags.worldgen.placed_feature
server event features will have to be added to their respective tags, in each example this will be done with the appropriate tag for the feature
A full list of available tags is also available here
Geodes
See the main page!
- 1st argument: A string, the name of the feature, if no namespace is provided, it will default to
kubejs_tfc
- 2nd argument: A consumer with several methods
outer(string)
: Accepts a block state and sets the outer layer of the geodemiddle(string)
: Accepts a block state and sets the middle layer of the geodeinner(string...)
: Accepts an array of weighted block states and sets the inner layer of the geode
- 3rd argument: A feature placement consumer
Example
// Builds a geode with an outer state of logs in the z direction, middle state of hardened basalt, and inner state of raw quartzite with 6 weight
// and cut copper with 1 weight. The placement is identical to TFC's default geode placement
onEvent('tfc.worldgen.data', event => {
event.buildTFCGeode('geode_test', e => {
e.outer('minecraft:oak_log[axis=z]')
e.middle('tfc:rock/hardened/basalt')
e.inner('6x tfc:rock/raw/quartzite', 'minecraft:cut_copper')
}, e => {
e.tfcBiome()
e.rarityFilter(500)
e.inSquare()
e.placement({
type: 'minecraft:height_range',
height: {
type: 'uniform',
min_inclusive: {
absolute: -48
},
max_inclusive: {
absolute: 32
}
}
})
})
})
onEvent('tags.worldgen.placed_feature', event => {
event.add('tfc:in_biome/veins', 'kubejs_tfc:geode_test')
})
Boulders
See the main page!
- 1st argument: A string, the name of the feature, if no namespace is provided, it will default to
kubejs_tfc
- 2nd argument: A consumer with one method:
state
- 1st argument: A block state, representing the ‘raw’ rock block of a rock type
- 2nd argument: A block state array, representing the blocks to be used when placing the boulder
- 3rd argument: A feature placement consumer
Example
// Builds a boulder which is made of the gravel and cobble corresponding to the type the boulder is in for limestone and shale
// The placement is identical to TFC's default boulder placement
onEvent('tfc.worldgen.data', event => {
event.buildTFCBoulder('ae2:boulder_test', e => {
e.state('tfc:rock/raw/limestone', 'tfc:rock/gravel/limestone', 'tfc:rock/cobble/limestone')
e.state('tfc:rock/raw/shale', 'tfc:rock/gravel/shale', 'tfc:rock/cobble/limestone')
}, e => {
e.rarityFilter(12)
e.inSquare()
e.heightMap('WORLD_SURFACE_WG')
e.flatEnough(e => {
e.flatness(0.4)
})
})
})
onEvent('tags.worldgen.placed_feature', event => {
event.add('tfc:feature/boulders', 'ae2:boulder_test')
})
Thin Spikes
See the main page!
- 1st argument: A string, the name of the feature, if no namespace is provided, it will default to
kubejs_tfc
- 2nd argument: A consumer with several methods:
state(string)
: Accepts a block state and sets the block to be used. Note: must be a thin spike blockradius(integer)
: Accepts an integer, in the range [1, 16], and sets the radius which to place spikes intries(integer)
: Accepts an integer and sets how many attempts should be made to place spikesheights(integer, integer)
: Accepts two integers, the first setting the minimum height of the spike, and the second the maximum
- 3rd argument: A feature placement consumer
Example
// Builds a thin spike feature using a custom block 'lava_spike'. The placement is identical to TFC's default for calcite
onEvent('tfc.worldgen.data', event => {
event.buildTFCThinSpike('thin_spike_test', e => {
e.state('kubejs:lava_spike')
e.radius(8)
e.tries(4)
e.heights(2, 6)
}, e => {
e.placement({
type: 'minecraft:count',
count: 4
})
e.inSquare()
e.placement({
type: 'minecraft:height_range',
height: {
type: 'biased_to_bottom',
min_inclusive: {
absolute: -32
},
max_inclusive: {
absolute: 100
}
}
})
})
})
onEvent('tags.worldgen.placed_feature', event => {
event.add('tfc:in_biome/underground_decoration', 'kubejs_tfc:thin_spike_test')
})
Veins
See the main page!
- 1st argument: A string, the name of the feature, if no namespace is provided, it will default to
kubejs_tfc
- 2nd argument: A consumer with several methods:
type(string)
: Accepts acluster
,disc
, orpipe
and sets the type of vein this feature will be, defaults tocluster
rarity(integer)
: Accepts an integer and sets the rarity, defaults to 60- Note: the rarity is 1 over the provided value, i.e. .rarity(3) would make the vein occur in 1/3 chunks on average
size(integer)
: Accepts an integer and sets the size, defaults to 8density(number)
: Accepts a number, in the range [0, 1], and sets the density of the vein, defaults to 0.2minY(object)
: Accepts either a vertical anchor json object or an integer, which will be treated as an absolute vertical anchor. Sets the minimum y level the vein will spawn atmaxY(object)
: Accepts either a vertical anchor json object or an integer, which will be treated as an absolute vertical anchor. Sets the maximum y level the vein will spawn atindicator(consumer)
: Accepts a consumer with several methods:depth(integer)
: Accepts an integer and sets the maximum depth below the surface the vein will spawn surface indicators, defaults to 35spread(integer)
: Accepts an integer and sets the maximum horizontal distance from a vein that an indicator will spawn, defaults to 15rarity(integer)
: Accepts an integer and sets the rarity to spawn indicators, as a fraction of horizontal locations the vein places ore blocks, defaults to 10indicators(string...)
: Accepts an array of weighted block states and sets the indicator(s) to use
replacementMap(consumer)
: Accepts a consumer with a method pair:replace(string...)
: A string array representing the list of blocks to replaced with:with(string...)
: An array of weighted block states, representing the ores of the vein, this method must be attached to areplace
method
salt(integer)
: Accepts an integer and sets the salt of the placement algorithm, defaults to the world’s seedbiomeFilter(string)
: Accepts string matching a biome tag and sets the filter for allowed biomes, defaults to allowing all biomes- If the type is
disc
the following method is also available:height(integer)
: Accepts an integer and sets the height of the vein, the size parameter will be interpreted as the radius
- If the type is
pipe
the following methods are also available:radius(integer)
: Accepts an integer and sets the radius of the vein, defaults to 3minSkew(integer)
: Accepts an integer and sets the minimum skew of the vein, defaults to 0maxSkew(integer)
: Accepts an integer and sets the maximum skew of the vein, defaults to 0minSlant(integer)
: Accepts an integer and sets the minimum slant of the vein, defaults to 0maxSlant(integer)
: Accepts an integer and sets the maximum slant of the vein, defaults to 0sign(number)
: Accepts a number, in the range [0, 1], and sets the sign of the slant, defaults to 0.5
Example
// Builds a vein that places
// copper blocks in dacite,
// gold and iron blocks in andesite,
// and dark oak and oak logs in rhyolite and basalt
// with an indicator of a custom loose rock[3]
onEvent('tfc.worldgen.data', event => {
event.buildTFCVein('vein_test', e => {
e.rarity(5)
e.size(20)
e.density(0.7)
e.minY(-20)
e.maxY(80)
e.indicator(e => {
e.depth(70)
e.spread(10)
e.rarity(17)
e.indicators('kubejs:custom_rock')
})
e.replacementMap(e => {
e.replace('tfc:rock/raw/rhyolite', 'tfc:rock/raw/basalt').with('8 minecraft:oak_log', '3 minecraft:dark_oak_log')
e.replace('tfc:rock/raw/andesite').with('9 minecraft:gold_block', '2 minecraft:iron_block')
e.replace('tfc:rock/raw/dacite').with('minecraft:copper_block')
})
})
})
onEvent('tags.worldgen.placed_feature', event => {
event.add('tfc:in_biome/veins', 'kubejs_tfc:vein_test')
})
If-Then
See the main page!
- 1st argument: A string, the name of the feature, if no namespace is provided, it will default to
kubejs_tfc
- 2nd argument: A string, the name of a feature to be placed
- 3rd argument: A string, the name of a feature to be placed if the first feature successfully places
- 4th argument: A feature placement consumer
Placing Features
World generation features are made up of two parts, their configuration and their placement, typically in separate files, but due to not being restricted to using raw json files, KubeJS TFC allows you to define a feature’s placement with its configuration through a feature placement consumer. Several of the methods can be seen in the above examples, but a full list will be provided here:
.tfcBiome()
Adds TFC’s biome placement modifier
.climate(consumer)
Adds TFC’s climate placement modifier
Accepts a consumer with several methods:
minTemp(number)
: Accepts a number and sets the minimum allowed average yearly temperaturemaxTemp(number)
: Accepts a number and sets the maximum allowed average yearly temperatureminRain(number)
: Accepts a number and sets the minimum allowed rainfallmaxRain(number)
: Accepts a number and sets the maximum allowed rainfallminForest(string)
: Accepts a forest type and sets the minimum required forest densitymaxForest(number)
: Accepts a forest type and sets the maximum required forest densityfuzzy(boolean)
: Accepts a boolean (default false). If true, the temperature and rainfall requirements will be probabilistic relative to the center point, with maximum density at the exact center, and zero density at the edges
.flatEnough(consumer)
Adds TFC’s flat enough placement modifier
Accepts a consumer with several methods:
flatness(number)
: Accepts a number, in the range [0, 1]. It describes the how many solid blocks, as a percentage the surrounding area must contain. Defaults to 0.5radius(integer)
: Accepts an integer and sets the radius around the initial position that the area is checked for solid blocks, defaults to 2maxDepth(integer)
: Accepts an integer and sets how deep from the original position the decorator should try and search, defaults to 4
.nearWater(integer)
Adds TFC’s near water placement modifier
Accepts an integer representing the distance to search for water
.shallowWater(optional integer)
Adds TFC’s shallow water placement modifier
Accepts an optional integer specifying the max depth of the water, defaults to 3
.underground()
Adds TFC’s underground placement modifier
.volcano(optional boolean, number)
Adds TFC’s volcano placement modifier
Accepts:
- An optional boolean which if true will place the feature at the exact center of any volcanoes, defaults to false
- A number, in the range [0, 1], representing the distance from the center of a volcano that this position must be in order to generate. 1 is the maximum radius of the volcano
.inSquare()
Adds Vanilla’s in_square
placement modifier
.rarityFilter(integer)
Adds Vanilla’s rarity_filter
placement modifier
Accepts an integer and sets the chance
parameter
.heightMap(string)
Adds Vanilla’s heightmap
placement modifier
Accepts a string and sets the height_map
parameter
.placement(object)
Adds any arbitrary placement modifier
Accepts either a json object, which will be treated as a placement modifier; a string, which will be treated as a placement modifier with the type specified by the given string; or a list containing json objects or strings, which will be individually processed
Examples
Please note these features are added to to the world using an outdated method of tagging, for how it should actually be done please refer to Adding Features above
The test boulder: The test geode: The test thin spike: A test vein indicator on the surface: A test vein in shale: A test vein in gabbro:
Rock Layers
TFC’s world is built around rock layers which can be modified through the modification of the rock_layer_settings
property of TFC’s dimension source, KubeJS TFC allows you to add to, remove, or modify these values through the tfc.rock_settings.register
startup event.
Note: These will only apply to worlds which do not have a data/minecraft/dimension/overworld.json
file in their applied datapacks, however their names can be referenced in the file just like TFC’s defaults
Adding a Layer
- 1st argument: The resource location of the rock layer you will be adding. Generally advised to use
kubejs
as the namespace as to not overwrite or be overwritten by another mod - 2nd argument: A consumer with several methods:
raw(string)
: Accepts a string representing the registry name of a block, sets the ‘raw’ block type for the rock layerhardened(string)
: Accepts a string representing the registry name of a block, sets the ‘hardened’ block type for the rock layergravel(string)
: Accepts a string representing the registry name of a block, sets the ‘gravel’ block type for the rock layercobble(string)
: Accepts a string representing the registry name of a block, sets the ‘cobble’ block type for the rock layersand(string)
: Accepts a string representing the registry name of a block, sets the ‘sand’ block type for the rock layersandstone(string)
: Accepts a string representing the registry name of a block, sets the ‘sandstone’ block type for the rock layerspike(string)
: Accepts a string representing the registry name of a block, sets the ‘spike’ block type for the rock layer. This value is optional- Note: The provided block must be an instance of RockSpikeBlock or the game may crash due to lacking the required block states
loose(string)
: Accepts a string representing the registry name of a block, sets the ‘loose’ block type for the rock layer. This value is optional- Note: The provided block must be an instance of LooseRockBlock or the game may crash due to lacking the required block states
top()
: Allows the rock layer to spawn on the top rock layer in the worldmiddle()
: Allows the rock layer to spawn on the middle rock layer in the worldbottom()
: Allows the rock layer to spawn on the bottom rock layer in the worldnoWarnings()
: A utility method which will disable non-critical warnings about the rock layer
Example
// Adds a default rock layer consisting of vanilla blocks and spawning only in the top rock layer of the world
onEvent('tfc.rock_settings.register', event => {
event.addDefaultLayer('kubejs:my_rock_layer', rock => {
rock.raw('minecraft:stone')
rock.hardened('minecraft:deepslate')
rock.cobble('minecraft:cobblestone')
rock.gravel('minecraft:gravel')
rock.sand('minecraft:sand')
rock.sandstone('minecraft:sandstone')
rock.top()
})
})
Removing a Layer
- 1st argument: The resource location of the rock layer you will be removing
- TFC’s layers are
tfc:
+ the name of the rock (‘chert’, ‘conglomerate’, etc.)
- TFC’s layers are
Example
// Removes the chert rock type from the list of available rock layers
onEvent('tfc.rock_settings.register', event => {
event.removeDefaultLayer('tfc:chert')
})
Modifying a Layer
- 1st argument: The resource location of the rock layer you will be modifying
- TFC’s layer are
tfc:
+ the name of the rock (‘andesite’, ‘basalt’, etc.)
- TFC’s layer are
- 2nd argument: A consumer with the same methods as adding a layer and some additional methods:
top(boolean)
: Accepts a boolean, determines if the layer is allowed to generate in the top rock layer of the world or notmiddle(boolean)
: Accepts a boolean, determines if the layer is allowed to generate in the middle rock layer of the world or notbottom(boolean)
: Accepts a boolean, determines if the layer is allowed to generate in the bottom rock layer of the world or not
Example
// Modifies the dacite rock layer to have no spike blocks and pink sand as its sand block
onEvent('tfc.rock_settings.register', event => {
event.modifyDefaultLayer('tfc:dacite', rock => {
rock.spike(null)
rock.sand('tfc:sand/pink')
})
})