<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.mutigeraffe.com/index.php?action=history&amp;feed=atom&amp;title=UtilityBiome%3AChunk_Features</id>
	<title>UtilityBiome:Chunk Features - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.mutigeraffe.com/index.php?action=history&amp;feed=atom&amp;title=UtilityBiome%3AChunk_Features"/>
	<link rel="alternate" type="text/html" href="https://wiki.mutigeraffe.com/index.php?title=UtilityBiome:Chunk_Features&amp;action=history"/>
	<updated>2026-10-20T09:04:17Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>https://wiki.mutigeraffe.com/index.php?title=UtilityBiome:Chunk_Features&amp;diff=494&amp;oldid=prev</id>
		<title>Maintenance script: UtilityBiome wiki</title>
		<link rel="alternate" type="text/html" href="https://wiki.mutigeraffe.com/index.php?title=UtilityBiome:Chunk_Features&amp;diff=494&amp;oldid=prev"/>
		<updated>2026-10-19T07:06:58Z</updated>

		<summary type="html">&lt;p&gt;UtilityBiome wiki&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;A &amp;#039;&amp;#039;&amp;#039;chunk feature&amp;#039;&amp;#039;&amp;#039; is a piece of Java code that Utility Biome runs once on every newly generated chunk whose biome matches. Waterfalls, overhangs, boulders or small ruins can be made this way, things the vanilla world generator cannot produce from its JSON files alone. [[BetterBiomes:Main Page|Better Biomes]] uses chunk features for many of its details, for example &amp;lt;code&amp;gt;betterbiomes:waterfall&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;betterbiomes:overhang&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
All types on this page are in the package &amp;lt;code&amp;gt;com.cyberpiratepenguin.utilitybiome.api&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Registering a feature ==&lt;br /&gt;
Register features in your own &amp;lt;code&amp;gt;setup()&amp;lt;/code&amp;gt;. A feature only affects chunks generated after it was registered. Chunks that already exist stay as they are.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@Override&lt;br /&gt;
protected void setup() {&lt;br /&gt;
    UtilityBiomeAPI.registerChunkFeature(ChunkFeature.named(&amp;quot;mymod:boulders&amp;quot;)&lt;br /&gt;
            .inBiomes(&amp;quot;Zone1_Tier*/Tile.Plains_*&amp;quot;)&lt;br /&gt;
            .chance(0.1)          // share of matching chunks&lt;br /&gt;
            .order(10)            // lower runs first&lt;br /&gt;
            .placer((chunk, random) -&amp;gt; {&lt;br /&gt;
                int x = random.nextInt(ChunkAccess.SIZE);&lt;br /&gt;
                int z = random.nextInt(ChunkAccess.SIZE);&lt;br /&gt;
                int y = chunk.height(x, z) + 1;&lt;br /&gt;
                chunk.setBlock(x, y, z, &amp;quot;Rock_Stone_Cobble&amp;quot;);&lt;br /&gt;
            }));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Setting !! Default !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;named(id)&amp;lt;/code&amp;gt; || required || Unique ID with your mod&amp;#039;s namespace, &amp;lt;code&amp;gt;mod:name&amp;lt;/code&amp;gt;. An ID without &amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt; is rejected.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;inBiomes(globs...)&amp;lt;/code&amp;gt; || all biomes || Globs on the biome at the &amp;#039;&amp;#039;&amp;#039;centre&amp;#039;&amp;#039;&amp;#039; of the chunk, written as &amp;lt;code&amp;gt;Zone/Tile.Name&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Zone/Custom.Name&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;*&amp;lt;/code&amp;gt; matches any number of characters, &amp;lt;code&amp;gt;?&amp;lt;/code&amp;gt; exactly one. The glob must match the whole name.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;chance(p)&amp;lt;/code&amp;gt; || 1 || Share of matching chunks that get the feature, from 0 to 1.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;order(n)&amp;lt;/code&amp;gt; || 0 || Features run in ascending order, ties by ID.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;placer(...)&amp;lt;/code&amp;gt; || required || The code that places the feature. Finishes the builder and returns the &amp;lt;code&amp;gt;ChunkFeature&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== What a placer may do ==&lt;br /&gt;
A &amp;lt;code&amp;gt;ChunkPlacer&amp;lt;/code&amp;gt; gets a &amp;lt;code&amp;gt;ChunkAccess&amp;lt;/code&amp;gt; for the new chunk and a random generator.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Only this chunk.&amp;#039;&amp;#039;&amp;#039; Local coordinates are 0–31 for x and z and 0–319 for y. Writing outside throws.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Not on the world thread.&amp;#039;&amp;#039;&amp;#039; Placers run in parallel for several chunks. Only read and write &amp;lt;code&amp;gt;chunk&amp;lt;/code&amp;gt;, and do not change any shared state of your own.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;All randomness from &amp;lt;code&amp;gt;random&amp;lt;/code&amp;gt;.&amp;#039;&amp;#039;&amp;#039; It is derived from the world seed, the feature ID and the chunk position. The same world always gives the same result, which matters because Hytale regenerates chunks that were never saved.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;All or nothing.&amp;#039;&amp;#039;&amp;#039; Writes are collected and only applied when the placer returns. If it throws, nothing of it is applied, a warning goes to the server log, and the chunk loads normally. Other features still run.&lt;br /&gt;
&lt;br /&gt;
=== ChunkAccess ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;chunkX()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;chunkZ()&amp;lt;/code&amp;gt; || Chunk position. Block x = &amp;lt;code&amp;gt;chunkX * 32 + x&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;height(x, z)&amp;lt;/code&amp;gt; || Highest non-transparent block of the column. Leaves count.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;block(x, y, z)&amp;lt;/code&amp;gt; || Block key without rotation, &amp;lt;code&amp;gt;&amp;quot;Empty&amp;quot;&amp;lt;/code&amp;gt; for air.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;isSolid(x, y, z)&amp;lt;/code&amp;gt; || Whether the block is solid.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fluid(x, y, z)&amp;lt;/code&amp;gt; || Fluid key, or &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;biome(x, z)&amp;lt;/code&amp;gt; || Zone and biome of the column, as a &amp;lt;code&amp;gt;BiomeSample&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;setBlock(x, y, z, key)&amp;lt;/code&amp;gt; || Sets a block. Keys are written as in the assets, with rotation if needed: &amp;lt;code&amp;gt;&amp;quot;Rock_Stone&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;Rock_Ice_Icicles|Pitch=180&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;setFluid(x, y, z, key)&amp;lt;/code&amp;gt; || Sets a fluid at full level, for example &amp;lt;code&amp;gt;&amp;quot;Water_Source&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
Constants: &amp;lt;code&amp;gt;ChunkAccess.SIZE&amp;lt;/code&amp;gt; = 32, &amp;lt;code&amp;gt;ChunkAccess.HEIGHT&amp;lt;/code&amp;gt; = 320.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
* Fluids live in their own layer next to the blocks. The block at that spot must be air or non-solid, otherwise the water disappears. Water set by a feature flows when the chunk loads.&lt;br /&gt;
* Inside a placer, &amp;lt;code&amp;gt;block&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fluid&amp;lt;/code&amp;gt; already see your own writes. &amp;lt;code&amp;gt;height&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;isSolid&amp;lt;/code&amp;gt; show the state before your placer ran.&lt;br /&gt;
* In 1.0.0, blocks placed by a chunk feature get no block entity. A chest placed this way has no storage, and crops do not grow. See [[UtilityBiome:Version History|Version History]].&lt;br /&gt;
&lt;br /&gt;
For boxes, spheres, building sites and terrain checks, see [[UtilityBiome:Structures|Structures]].&lt;br /&gt;
&lt;br /&gt;
== Checking features in the game ==&lt;br /&gt;
* &amp;lt;code&amp;gt;/ub features&amp;lt;/code&amp;gt; lists all registered features, their chance, their biomes and how often each was placed since the server started.&lt;br /&gt;
* &amp;lt;code&amp;gt;/ub feature &amp;amp;lt;id&amp;amp;gt;&amp;lt;/code&amp;gt; teleports you to a spot where the feature was placed.&lt;br /&gt;
* Every placement is written to the server log with its position and number of changes. Every 30 seconds at most, a summary line shows how many chunks were generated, how many features were placed or failed and the slowest time per chunk.&lt;br /&gt;
See [[UtilityBiome:Commands|Commands]].&lt;br /&gt;
&lt;br /&gt;
=== Test features ===&lt;br /&gt;
For developing Utility Biome itself, the environment variable &amp;lt;code&amp;gt;UTILITYBIOME_TEST_FEATURES&amp;lt;/code&amp;gt; (any value) registers two test features at start:&lt;br /&gt;
* &amp;lt;code&amp;gt;ub:test_pillar&amp;lt;/code&amp;gt;: in 5 % of chunks, a white crystal pillar in the middle of the chunk with a water source on top.&lt;br /&gt;
* &amp;lt;code&amp;gt;ub:test_broken&amp;lt;/code&amp;gt;: throws on purpose in 2 % of chunks, to check that nothing is applied and a warning is logged.&lt;br /&gt;
Never set it on a server people play on.&lt;br /&gt;
&lt;br /&gt;
{{UtilityBiome Nav}}&lt;/div&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
</feed>