SkillAgentSearch skills...

Noise4j

:octocat: Simple map generators for Java applications.

Install / Use

/learn @czyzby/Noise4j
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Noise4J

Simple map generators based on various procedural content generation tutorials.

I really did not want to enforce any kind of map&tile system that you would have to modify, extend or even copy to your own implementation. The generators work on a simple 1D float array with a lightweight wrapper, that basically allows to use it as a 2D array. Result number ranges are never enforced - you can generate map with [0,1] values range (like in the examples), as well as [0,1000] - whatever suits you bests. Grid class also comes with some common math operations, so you can manually modify the values if you feel the need to.

Dependency

Gradle dependency:

    compile 'com.github.czyzby:noise4j:0.1.0'

LibGDX

While Noise4J was created with LibGDX games in mind, it has no external dependencies. It's GWT- and Java 6-compatible, so including it in LibGDX projects is pretty straightforward. Start with adding the mentioned Gradle dependency to the core project:

    compile 'com.github.czyzby:noise4j:0.1.0'

You need to inherit Noise4J GWT module in your GdxDefinition, otherwise GWT compiler will not recognize the classes:

	<inherits name='com.github.czyzby.noise4j.Noise4J' />

Also, don't forget to also include the sources dependency in GWT project: compile 'com.github.czyzby:noise4j:0.1.0:sources'.

Noise4J does not use reflection, so its files usually do not need to be registered in any additional way.

Noise generator

LibGDX usage example:

public class Example extends ApplicationAdapter {
    private SpriteBatch batch;
    private Texture texture;

    @Override
    public void create() {
        final Pixmap map = new Pixmap(512, 512, Format.RGBA8888);
        final Grid grid = new Grid(512);

        final NoiseGenerator noiseGenerator = new NoiseGenerator();
        noiseStage(grid, noiseGenerator, 32, 0.6f);
        noiseStage(grid, noiseGenerator, 16, 0.2f);
        noiseStage(grid, noiseGenerator, 8, 0.1f);
        noiseStage(grid, noiseGenerator, 4, 0.1f);
        noiseStage(grid, noiseGenerator, 1, 0.05f);

        final Color color = new Color();
        for (int x = 0; x < grid.getWidth(); x++) {
            for (int y = 0; y < grid.getHeight(); y++) {
                final float cell = grid.get(x, y);
                color.set(cell, cell, cell, 1f);
                map.drawPixel(x, y, Color.rgba8888(color));
            }
        }

        texture = new Texture(map);
        batch = new SpriteBatch();
        map.dispose();
    }

    private static void noiseStage(final Grid grid, final NoiseGenerator noiseGenerator, final int radius,
            final float modifier) {
        noiseGenerator.setRadius(radius);
        noiseGenerator.setModifier(modifier);
        // Seed ensures randomness, can be saved if you feel the need to
        // generate the same map in the future.
        noiseGenerator.setSeed(Generators.rollSeed());
        noiseGenerator.generate(grid);
    }

    @Override
    public void render() {
        Gdx.gl.glClearColor(0f, 0f, 0f, 1f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.begin();
        batch.draw(texture, 0f, 0f);
        batch.end();
    }

    @Override
    public void dispose() {
        texture.dispose();
        batch.dispose();
    }
}

NoiseGenerator

Cellular automata generator

LibGDX usage example:

public class Example extends ApplicationAdapter {
    private SpriteBatch batch;
    private Texture texture;

    @Override
    public void create() {
        final Pixmap map = new Pixmap(512, 512, Format.RGBA8888);
        final Grid grid = new Grid(512);

        final CellularAutomataGenerator cellularGenerator = new CellularAutomataGenerator();
        cellularGenerator.setAliveChance(0.5f);
        cellularGenerator.setIterationsAmount(4);
        cellularGenerator.generate(grid);

        final Color color = new Color();
        for (int x = 0; x < grid.getWidth(); x++) {
            for (int y = 0; y < grid.getHeight(); y++) {
                final float cell = grid.get(x, y);
                color.set(cell, cell, cell, 1f);
                map.drawPixel(x, y, Color.rgba8888(color));
            }
        }

        texture = new Texture(map);
        batch = new SpriteBatch();
        map.dispose();
    }

    @Override
    public void render() {
        Gdx.gl.glClearColor(0f, 0f, 0f, 1f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.begin();
        batch.draw(texture, 0f, 0f);
        batch.end();
    }

    @Override
    public void dispose() {
        texture.dispose();
        batch.dispose();
    }
}

CellularAutomataGenerator

Bigger radius:

        final CellularAutomataGenerator cellularGenerator = new CellularAutomataGenerator();
        cellularGenerator.setAliveChance(0.5f);
        cellularGenerator.setRadius(2);
        cellularGenerator.setBirthLimit(13);
        cellularGenerator.setDeathLimit(9);
        cellularGenerator.setIterationsAmount(6);
        cellularGenerator.generate(grid);

CellularAutomataGenerator Use more iterations for a smoother map. Keep in mind that using a big radius can make the algorithm significantly slower.

Dungeon generator

LibGDX usage example:

public class Example extends ApplicationAdapter {
    private SpriteBatch batch;
    private Texture texture;

    @Override
    public void create() {
        final Pixmap map = new Pixmap(512, 512, Format.RGBA8888);
        final Grid grid = new Grid(512); // This algorithm likes odd-sized maps, although it works either way.

        final DungeonGenerator dungeonGenerator = new DungeonGenerator();
        dungeonGenerator.setRoomGenerationAttempts(500);
        dungeonGenerator.setMaxRoomSize(75);
        dungeonGenerator.setTolerance(10); // Max difference between width and height.
        dungeonGenerator.setMinRoomSize(9);
        dungeonGenerator.generate(grid);

        final Color color = new Color();
        for (int x = 0; x < grid.getWidth(); x++) {
            for (int y = 0; y < grid.getHeight(); y++) {
                final float cell = 1f - grid.get(x, y);
                color.set(cell, cell, cell, 1f);
                map.drawPixel(x, y, Color.rgba8888(color));
            }
        }

        texture = new Texture(map);
        batch = new SpriteBatch();
        map.dispose();
    }

    @Override
    public void render() {
        Gdx.gl.glClearColor(0f, 0f, 0f, 1f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.begin();
        batch.draw(texture, 0f, 0f);
        batch.end();
    }

    @Override
    public void dispose() {
        texture.dispose();
        batch.dispose();
    }
}

DungeonGenerator

Different room types are also supported. While you can implement RoomType and fully control how rooms are "carved" in the walls, you can also use some default proposed room types with dungeonGenerator.addRoomTypes(DefaultRoomType.values());:

DungeonGenerator

This dungeon can be also used to create "perfect" mazes (as in: with one way to solve them):

        final DungeonGenerator dungeonGenerator = new DungeonGenerator();
        dungeonGenerator.setRoomGenerationAttempts(200);
        dungeonGenerator.setMaxRoomSize(25);
        dungeonGenerator.setTolerance(6);
        dungeonGenerator.setMinRoomSize(9);
        dungeonGenerator.setWindingChance(0.5f); // More chaotic!
        dungeonGenerator.setDeadEndRemovalIterations(5); // Introducing dead ends.
        dungeonGenerator.setRandomConnectorChance(0f); // One way to solve the maze.
        dungeonGenerator.generate(grid);

DungeonGenerator

While these might seem chaotic (or even somewhat unplayable) at first sight, the generator is highly flexible - and no one is forcing you to create such huge maps(/rooms) either. This is a simple set-up for a rogue-like (256x256px, scaled x2):

DungeonGenerator

In case you're wondering about the settings - it's simply new DungeonGenerator().generate(grid). This is what comes out when you use the default setup, which features relatively small rooms. The one below, on the other hand, has custom min/max room sizes and rooms amount:

DungeonGenerator

Combined

NoiseGenerator and CellularAutomataGenerator combined can generate maps similar to this:

NoiseGenerator + CellularAutomataGenerator

On this scale, this might look somewhat like some cavern system, but you don't have to generate maps that big (or with the same parameters, for that matter). Note that here each tile is represented by a single pixel - given than the map's size is 512x512 tiles, with a relatively small tile image size at 16x16px, this map would still need 67108864 (8192x8192) pixels to be drawn. With a smaller map and appropriate tiles, such map could be just as easily used to represent islands, for example.

What can I do with the Grid...

By default, noise generator adds [0, modifier] to each cell on each generation, smoothing values between the regions that you define. It ends up with "realistic" m

View on GitHub
GitHub Stars108
CategoryDevelopment
Updated20d ago
Forks14

Languages

Java

Security Score

100/100

Audited on Mar 19, 2026

No findings