Skip to content

Commit

Permalink
Update spawn algorithm for 1.21.2 + cmake + more
Browse files Browse the repository at this point in the history
* added basic support for cmake (#127)
* renamed Winter Drop version from MC_1_21_3 to MC_1_21_WD
* updated world spawn location for 1.21.2 (cubiomes-viewer #340)
* tweaked mc version to text conversion (#128)
* removed properties field in structure config and added dimension field instead
* moved biome tree selection back to biomenoise.c as it's slightly faster and avoids globals
  • Loading branch information
Cubitect committed Nov 9, 2024
1 parent 6d1a190 commit 89df24c
Show file tree
Hide file tree
Showing 12 changed files with 138 additions and 146 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,15 @@ int main()
You can compile this code either by directly adding a target to the makefile via
```
$ cd cubiomes
$ make libcubiomes
$ make
```
...or you can compile and link to a cubiomes archive using either of the following commands.
```
$ gcc find_biome_at.c libcubiomes.a -fwrapv -lm # static
$ gcc find_biome_at.c -L. -lcubiomes -fwrapv -lm # dynamic
```
Both commands assume that your source code is saved as `find_biome_at.c` in the cubiomes working directory. If your makefile is configured to use pthreads, you may also need to add the `-lpthread` option to the compiler.
The option `-fwrapv` enforces two's complement for signed integer overflow, which this library relies on. It is not strictly necessary for this example as the library should already be compiled with this flag, but it is good practice to prevent undefined behaviour.
Both commands assume that your source code is saved as `find_biome_at.c` in the cubiomes working directory. If your makefile is configured to use pthreads, you may also need to add the `-lpthread` option for the compiler.
The option `-fwrapv` enforces two's complement for signed integer overflow, which is otherwise undefined behavior. It is not really necessary for this example, but it is a common pitfall when dealing with code that emulates the behavior of Java.
Running the program should output:
```
$ ./a.out
Expand All @@ -78,9 +78,9 @@ Seed 262 has a Mushroom Fields biome at block position (0, 0).

### Biome Generation in a Range

We can also generate biomes for an area or volume using `genBiomes()`. This will utilize whatever optimizations are available for the generator and can be much faster than generating each position individually. (The layered generators for versions up to 1.17 will benefit significantly more from this than the noise-based ones.)
We can also generate biomes for an area or volume using `genBiomes()`. This will utilize whatever optimizations are available for the generator, which can be much faster than generating each position individually. (The layered generators for versions up to 1.17 will benefit significantly more from this than the noise-based ones.)

Before we can generate the biomes for an area or volume, we need to define the bounds with a `Range` structure and allocate the necessary buffer using `allocCache()`. The `Range` is described by a scale, position, and size, where each cell inside the `Range` represents the `scale` of many blocks in the horizontal axes. The vertical direction is treated separately and always follows the biome coordinate scaling of 1:4, except for when `scale == 1`, in which case the vertical scaling is also 1:1.
Before we can generate the biomes for an area or volume, we need to define the bounds with a `Range` structure and allocate the necessary buffer using `allocCache()`. The `Range` is described by a scale, position, and size, where each cell inside the `Range` represents an amount of `scale` blocks in the horizontal axes. The vertical direction is treated separately and always follows the biome coordinate scaling of 1:4, except for when `scale == 1`, in which case the vertical scaling is also 1:1.

The only supported values for `scale` are 1, 4, 16, 64, and (for the Overworld) 256. For versions up to 1.17, the scale is matched to an appropriate biome layer and will influence the biomes that can generate.

Expand Down
68 changes: 49 additions & 19 deletions biomenoise.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
#include "biomenoise.h"

#include "tables/btree18.h"
#include "tables/btree192.h"
#include "tables/btree19.h"
#include "tables/btree20.h"
#include "tables/btree21wd.h"

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
Expand Down Expand Up @@ -1359,9 +1365,7 @@ int getOldBetaBiome(float t, float h)
}


#if !DEBUG
static inline ATTR(hot, pure, always_inline)
#endif
static
uint64_t get_np_dist(const uint64_t np[6], const BiomeTree *bt, int idx)
{
uint64_t ds = 0, node = bt->nodes[idx];
Expand All @@ -1380,9 +1384,7 @@ uint64_t get_np_dist(const uint64_t np[6], const BiomeTree *bt, int idx)
return ds;
}

#if !DEBUG
static inline ATTR(hot, pure)
#endif
static
int get_resulting_node(const uint64_t np[6], const BiomeTree *bt, int idx,
int alt, uint64_t ds, int depth)
{
Expand Down Expand Up @@ -1428,28 +1430,56 @@ int get_resulting_node(const uint64_t np[6], const BiomeTree *bt, int idx,
return leaf;
}

ATTR(hot, flatten)
int climateToBiome(int mc, const uint64_t np[6], uint64_t *dat)
{
if (mc < MC_1_18 || mc > MC_NEWEST)
return -1;

const BiomeTree *bt = &g_btree[mc - MC_1_18];
int alt = 0;
static const BiomeTree btree18 = {
btree18_steps, &btree18_param[0][0], btree18_nodes, btree18_order,
sizeof(btree18_nodes) / sizeof(uint64_t)
};
static const BiomeTree btree192 = {
btree192_steps, &btree192_param[0][0], btree192_nodes, btree192_order,
sizeof(btree192_nodes) / sizeof(uint64_t)
};
static const BiomeTree btree19 = {
btree19_steps, &btree19_param[0][0], btree19_nodes, btree19_order,
sizeof(btree19_nodes) / sizeof(uint64_t)
};
static const BiomeTree btree20 = {
btree20_steps, &btree20_param[0][0], btree20_nodes, btree20_order,
sizeof(btree20_nodes) / sizeof(uint64_t)
};
static const BiomeTree btree21wd = {
btree21wd_steps, &btree21wd_param[0][0], btree21wd_nodes, btree21wd_order,
sizeof(btree21wd_nodes) / sizeof(uint64_t)
};

const BiomeTree *bt;
int idx;
uint64_t ds = -1;

if (dat)
{
alt = (int) *dat;
ds = get_np_dist(np, bt, alt);
}
if (mc >= MC_1_21_WD)
bt = &btree21wd;
else if (mc >= MC_1_20_6)
bt = &btree20;
else if (mc >= MC_1_19_4)
bt = &btree19;
else if (mc >= MC_1_19_2)
bt = &btree192;
else
bt = &btree18;

idx = get_resulting_node(np, bt, 0, alt, ds, 0);
if (dat)
{
int alt = (int) *dat;
uint64_t ds = get_np_dist(np, bt, alt);
idx = get_resulting_node(np, bt, 0, alt, ds, 0);
*dat = (uint64_t) idx;
}

else
{
idx = get_resulting_node(np, bt, 0, 0, -1, 0);
}

return (bt->nodes[idx] >> 48) & 0xFF;
}

Expand Down
13 changes: 2 additions & 11 deletions biomenoise.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,15 +159,6 @@ extern "C"
{
#endif

//==============================================================================
// Globals
//==============================================================================

// The global biome tree definitions.
// By default, these are defined in biometree.c and tables/btreeXX.h
extern BiomeTree g_btree[MC_NEWEST - MC_1_18 + 1];


//==============================================================================
// Noise
//==============================================================================
Expand Down Expand Up @@ -267,8 +258,8 @@ double approxSurfaceBeta(const BiomeNoiseBeta *bnb, const SurfaceNoiseBeta *snb,
int getOldBetaBiome(float t, float h);

/**
* Uses the global biome tree definition (g_btree) to map a noise point
* (i.e. climate) to the corresponding overworld biome.
* Uses the global biome tree definitions (see tables/btreeXX.h)
* to map a noise point (i.e. climate) to the corresponding overworld biome.
*/
int climateToBiome(int mc, const uint64_t np[6], uint64_t *dat);

Expand Down
2 changes: 1 addition & 1 deletion biomes.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ int biomeExists(int mc, int id)
return 1;

if (id == pale_garden)
return mc >= MC_1_21_3;
return mc >= MC_1_21_WD;

if (id == cherry_grove)
return mc >= MC_1_20;
Expand Down
11 changes: 6 additions & 5 deletions biomes.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ enum MCVersion
MC_1_19_2,
MC_1_19_4, MC_1_19 = MC_1_19_4,
MC_1_20_6, MC_1_20 = MC_1_20_6,
MC_1_21_2,
MC_1_21_3, // (Winter Drop version TBA)
MC_1_21 = MC_1_21_2,
MC_NEWEST = MC_1_21_3,
MC_1_21_1,
MC_1_21_2, // = 1.21.3
MC_1_21_WD, // Winter Drop, version TBA
MC_1_21 = MC_1_21_WD,
MC_NEWEST = MC_1_21,
};

enum Dimension
Expand Down Expand Up @@ -170,7 +171,7 @@ enum BiomeID
mangrove_swamp = 184,
// 1.20
cherry_grove = 185,
// 1.21.3
// 1.21 Winter Drop
pale_garden = 186,
};

Expand Down
30 changes: 0 additions & 30 deletions biometree.c

This file was deleted.

Loading

0 comments on commit 89df24c

Please sign in to comment.