An updated fork of the isotope hex package.
  • Rust 80.2%
  • Elixir 18.8%
  • Dockerfile 0.6%
  • Nix 0.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Patrick W. 03c39d39b0
Some checks failed
ci / test (1.18, sickday/elixir:ci-1.18) (push) Failing after 11s
ci / test (1.19, sickday/elixir:ci-1.19) (push) Failing after 11s
ci / musl (push) Successful in 6s
ci / test (1.20, sickday/elixir:ci, true) (push) Failing after 12s
fix: exclude compiled NIF from the hex package
2026-07-09 13:32:07 -04:00
.forgejo feat: update 7/9 2026-07-09 12:44:58 -04:00
benchmark Fix package on hex and improve aliases 2021-06-20 20:28:42 +00:00
examples v0.4.0: Parallelize noise generation with Rayon 2026-04-12 11:21:55 -04:00
images Rename project 2021-06-20 06:30:49 +00:00
lib v0.4.0: Parallelize noise generation with Rayon 2026-04-12 11:21:55 -04:00
native/noise feat: update 7/9 2026-07-09 12:44:58 -04:00
priv Add priv/native directory to git repo and ecto 2021-06-20 20:52:26 +00:00
test v0.4.0: Parallelize noise generation with Rayon 2026-04-12 11:21:55 -04:00
.credo.exs Add credo library 2021-06-18 01:08:41 +00:00
.envrc Upgrade from nix shell to flake 2021-08-31 07:11:14 -03:00
.formatter.exs Add rustler NIFs and module API 2021-06-17 20:55:50 +00:00
.gitignore feat: update 7/9 2026-07-09 12:44:58 -04:00
CHANGELOG.md fix: exclude compiled NIF from the hex package 2026-07-09 13:32:07 -04:00
flake.lock Bump dependencies and version, remove ex_png dependency 2023-05-20 13:09:14 -03:00
flake.nix v0.4.0: Parallelize noise generation with Rayon 2026-04-12 11:21:55 -04:00
LICENSE Create LICENSE 2021-06-17 19:26:55 +00:00
mix.exs fix: exclude compiled NIF from the hex package 2026-07-09 13:32:07 -04:00
mix.lock feat: update 7/9 2026-07-09 12:44:58 -04:00
README.md feat: wrap up 0.5.0 2026-07-09 12:54:52 -04:00
shell.nix v0.4.0: Parallelize noise generation with Rayon 2026-04-12 11:21:55 -04:00

Isotope (isotope_118)

Isotope is a library for generating noise in Elixir, backed by a Rust NIF.

Noise maps are returned as compact binaries of packed f32 values (~4 bytes per value), making them suitable for generating large maps without excessive memory usage.

This is a fork. isotope_118 is a fork of isotope by Vinícius Müller / the Phiriq Project, published because upstream did not support Elixir 1.18+ and had seen no releases. Nearly all of the design and code is theirs. The fork adds Elixir 1.18+ support, a current rustler, and the changes listed in CHANGELOG.md. Issues with this package belong here, not upstream.

The noise implementation is a vendored copy of bracket-noise (a Rust port of Auburn's original FastNoise, not FastNoise Lite), with several cellular-noise bugs fixed. See native/noise/src/fastnoise.rs and native/noise/THIRD_PARTY_LICENSES.

Installation

Add isotope_118 to your list of dependencies in mix.exs:

def deps do
  [
    {:isotope_118, "~> 0.5"}
  ]
end

And running mix deps.get && mix deps.compile.

A Rust toolchain is required to build the NIF: rustc 1.91 or newer (rustler 0.38's minimum). Distro packages often lag — rustup is the safe route.

Usage

Generating a Noise Map

opts = %Isotope.Options{
  seed: 42,
  noise_type: :simplex_fractal,
  frequency: 0.01,
  fractal_options: %Isotope.Options.Fractal{octaves: 4}
}

{:ok, noise} = Isotope.Noise.new(opts)

# Returns an %Isotope.NoiseMap{} struct
nm = Isotope.Noise.noise_map(noise, {1000, 1000})

Accessing Values

# Single value at column x, row y
Isotope.NoiseMap.get(nm, 50, 50)

# Entire row as a list of floats
Isotope.NoiseMap.row(nm, 0)

# Dimensions
{width, height} = Isotope.NoiseMap.size(nm)

# Convert to nested list [[float()]]
Isotope.NoiseMap.to_list(nm)

Using with Enum

Isotope.NoiseMap implements Enumerable, iterating over rows:

# Average value per row
Enum.map(nm, fn row -> Enum.sum(row) / length(row) end)

# Visualize in the terminal
Isotope.Utils.show_noisemap(nm)

Chunks (Infinite Worlds / Tiling)

Generate a noise map starting at an arbitrary coordinate:

chunk = Isotope.Noise.chunk(noise, {512, 512}, 256, 256)

Sampling Individual Points

# 2D
value = Isotope.Noise.get_noise(noise, {1.5, 2.5})

# 3D
value = Isotope.Noise.get_noise(noise, {1.5, 2.5, 3.5})

Noise Types

Isotope supports the following noise types via the :noise_type option:

Type Atom
Simplex :simplex
Simplex Fractal :simplex_fractal
Perlin :perlin
Perlin Fractal :perlin_fractal
Value :value
Value Fractal :value_fractal
Cubic :cubic
Cubic Fractal :cubic_fractal
Cellular (Voronoi) :cellular
White Noise :white

Options

See Isotope.Options, Isotope.Options.Fractal, and Isotope.Options.Cellular for all available configuration.

%Isotope.Options{
  seed: 1337,               # Random seed
  noise_type: :simplex,     # Noise algorithm
  frequency: 0.01,          # Controls noise scale
  interpolation: :quintic,  # :linear | :hermite | :quintic
  fractal_options: %Isotope.Options.Fractal{
    fractal_type: :fbm,     # :fbm | :billow | :rigid_multi
    octaves: 3,             # Number of fractal layers
    lacunarity: 2.0,        # Frequency multiplier per octave
    gain: 0.5               # Amplitude multiplier per octave
  },
  cellular_options: %Isotope.Options.Cellular{
    distance_function: :euclidean,  # :euclidean | :manhattan | :natural
    return_type: :cell_value,       # :cell_value | :distance | :distance2 | ...
    distance_indices: {0, 1},
    jitter: 0.45
  }
}

For more information, check the documentation here.

Examples

You can check and run the examples in the examples folder.

mix run examples/<example>.exs

Images

Output of the terrain.exs example script Output of the visualization.exs example script