A rewrite of Cubiomes but in Julia, intended to be (much) easier to use and to contribute to, and faster.
Warning
The code is still in early development, and everything can change at any time. This repo should be seen as a proof of concept and nothing else.
-
Readability and ease of use: Julia is a high-level language, which makes the code easier to read and understand. Of course to be fast, it is sometimes necessary to write more complex code, but if it is simply to use an API (like the one of Cubiomes), it a very easy Python-like language.
-
Performance: Julia is almost as fast as C. For this case, it is in fact faster because is it very easy to parallelize the code or to easily know where the bottlenecks are with the built-in profiler.
The package is still early in development, so it is not yet registered. You can install it via the github repository, in the Julia REPL:
julia> ] add github.com/arnaud-ma/cubiomes.jl
It is still a work in progress, so the API is not yet stable at all. The nether generation should be working, here is an example:
using Cubiomes.BiomeGeneration
seed = "hello world" # (1)
nether_generator = Nether(seed) # (2)
mc_map = MCMap(-1000:1000, -1000:1000) # (3)
gen_biomes!(nether_generator, mc_map, 📏"1:4") # (4)
using Plots, Cubiomes.Display
plot(to_color(mc_map)) # (5)
Let's explain step by step:
- The seed is exactly the same as in Minecraft. It can be any string or integer.
- We create a generator, that is mandatory to generate the biomes. It's there that we can pass a seed.
- We create a
MCMap
object, that will store the biomes. It can be 2D or 3D (depending if the y coordinate is provided or not). Biomes are stored as enum values. You can access to it with the exact same coordinates as in Minecraft (e.g.mc_map[0, 0, 0]
will give you the biome at the origin of the world). At the moment of the code, the map is full ofBIOME_NONE
values because we did not generate the biomes yet. - We generate the biomes with the
gen_biomes!
function. It will fill theMCMap
with the biomes. The last argument is the scale of the biomes, i.e. how many blocks in the world correspond to one biome value in the map. For example, with a scale of 4, one biome value in the map corresponds to a square of 4x4 blocks in the world. The only supported values are📏"1:1"
,📏"1:4"
,📏"1:16"
and📏"1:64"
. The symbol name is ":straight_ruler:". - We can visualize the map with
plot
. The colors are the same as in Minecraft, so you can easily recognize the biomes.
- JavaRandom
- Xoroshiro128PlusPlus
- Test with Suppositions.jl
- Perlin noise
- Octaves noise
- Simplex noise
- Double Perlin noise
-
Use the broadcasting interface for the
MCMap
object, to be able to use the dot syntax, i.e.mc_map = MCMap(-1000:1000, -1000:1000) mc_map .= get_biomes.(nether_generator, mc_map, 📏"1:4")
instead of the
gen_biomes!
function.
- Nether generation
- Overworld 1.18+ generation
- Overworld beta generation
- Overworld generation
- End generation
- Structure generation
- Use of recipes for the plots of maps without the need of depending on Plots.jl
- Threading for the biome generation
- GPU acceleration for the biome generation
- Make the Minecraft version types instead of enums and dispatch the functions instead of if checks. I don't really know if it's a good idea or not. See the julia doc: The-dangers-of-abusing-multiple-dispatch.
- The code should be formatted with
using JuliaFormatter; format(".")
. - For random generator, each function that modifies the state inplace should be prefixed with a
🎲
(:game_die:) - For array manipulation, each function that modifies the array inplace should be prefixed with a
!
. - Each new feature should be tested with unit tests (with the
Test
module) and if possible with property-based tests (with Suppositions.jl)
Java >= 17 is required to run the tests. You can run the tests with:
julia> ] test Cubiomes
To not include Aqua.jl tests:
julia> using Pkg; Pkg.test("Cubiomes"; test_args=["not_aqua"])
To run the tests with the coverage:
julia> using Cubiomes, LocalCoverage
julia> LocalCoverage.generate_coverage("Cubiomes")