Code Monkey home page Code Monkey logo

mapgen4's Introduction

Mapgen4

http://unmaintained.tech/badge.svg

Mapgen4 is a procedural wilderness map generator I wrote during 2017 and 2018, and updated in 2023. It’s written in JavaScript/TypeScript and designed to:

  • run fast enough to regenerate in real time as you paint terrain
  • look pretty instead of generating realistic terrain

https://www.redblobgames.com/maps/mapgen4/blog/screenshot15-small.jpg

Install

If you use yarn 1:

yarn global add esbuild
yarn install
./build.sh

If you use npm:

npm install -g esbuild
npm install
./build.sh

Run python3 -m http.server 8000, then visit http://localhost:8000/embed.html in your browser.

Background

I have a series of blog posts about how I made these maps:

It’s a continuation of ideas I developed for mapgen2 back in 2010, but at a much larger scale. The underlying code can support 1 million+ Voronoi cells (change spacing in config.js to 0.7), including a very detailed river network, but the rendering code and other parameters are designed to look prettiest around 25k cells.

There’s plenty more that could be done to make it even faster and prettier. There are plenty of features that could be added, such as drawing your own rivers, sphere output, natural resources, towns, forests, names, roads, and nations, but I’m leaving those for a future project.

Code

The entry point is mapgen4.ts. The main data structures are in the dual-mesh/ folder. The map generation algorithms are in map.ts. The input painting is in painting.ts. The output rendering is in render.ts. Calculations are in worker.ts. Calculations shared between the worker and renderer are in geometry.ts.

Although the code is TypeScript, I’m using esbuild for building, which does not check the types. Instead, I have type checking in the IDE only.

License

Mapgen4 and helper libraries I wrote (dual-mesh, prng) are licensed under Apache v2. You can use this code in your own project, including commercial projects.

The map generator uses these libraries:

The rendering code uses these libraries:

  • regl from Mikola Lysenko is licensed under the MIT license.
  • gl-matrix from Brandon Jones, Colin MacKenzie IV is licensed under the MIT license.

The build step uses esbuild from Evan Wallace, licensed under the MIT license

mapgen4's People

Contributors

redblobgames avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mapgen4's Issues

[Question] How to change river color?

Hello,

I really impressed with this and thank you so much for your sharing this wonderful project.

I tried your code as instructed, and everything works perfect!!! Great!!

Can I ask one thing? How to change the River color? I was looking colormap.js and render.js and tried several changes, but still failed to change the river color...
I'm now trying to extract height map from your mapgen4 image but river color gave me some problem... I want to make river color more dark.... (close to rgb 50,50,50)

Any advice or hint will be highly appreciate!!!
Thanks for this great job!!!

npm run build error

Hi, please help me
when i run the last cmd 'npm run build', the console will show me

Error: ENOENT: no such file or directory, lstat 'D:\work\Git\mapgen4\node_modules\@redblobgames\dual-mesh\dist\dual-mesh.js' at Error (native) npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! @redblobgames/[email protected] build: browserify mapgen4.js -g uglifyify -o build/_bundle.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @redblobgames/[email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\zsj\AppData\Roaming\npm-cache_logs\2019-09-23T03_46_10_224Z-debug.log`

How do I translate to a tilemap?

How do I translate the generated map to a tilemap?

I want to store all the information in a matrix, any approach on how would you do this?

How to know if region is coast, water or ocean?

Is it possible to know wheter a given region (polygon) is a coast or not, ocean or not and water or not?
I saw this inside the setMapGeometry function:
let coast = r_elevation[r1] < 0.0 || r_elevation[r2] < 0.0;
My goal is to create 3 new array properties "r_coast" ,"r_ocean" and "r_water" with booleans. Just like mapgen2 does.
But i don't quite understand it.

Adding trees

Just wanted to start by saying thank you! This is an amazing project.

I'm attempting to implement trees. While I think I have a decent strategy in mind (draw sprites based on moisture, elevation, and aspect), I can tell I have a lot of learning to do before I'm able to contribute anything of use.

You had mentioned on your blog that trees were possibly on the horizon. Do you have any example code or ideas that I could learn from while I get up to speed?

try to export heightmap, but get wired result

In worker.js

            // create heightmap
            const size = 1000;
            const heightmap = [];
            for (let y = 0; y < size; ++y) {
                const row = [];
                for (let x = 0; x < size; ++x) {
                    row.push(0);
                }
                heightmap.push(row);
            }
            const mesh = map.mesh;
            for (let t = 0; t < mesh.numTriangles; ++t) {
                const s = 3 * t;
                const r0 = mesh.s_begin_r(s);
                const ax = mesh.r_x(r0);
                const ay = mesh.r_y(r0);
                const az = -map.r_elevation[r0];
                const r1 = mesh.s_begin_r(s + 1);
                const bx = mesh.r_x(r1);
                const by = mesh.r_y(r1);
                const bz = -map.r_elevation[r1];
                const r2 = mesh.s_begin_r(s + 2);
                const cx = mesh.r_x(r2);
                const cy = mesh.r_y(r2);
                const cz = -map.r_elevation[r2];
                let minX = Infinity;
                let maxX = -Infinity;
                minX = Math.min(minX, ax);
                minX = Math.min(minX, bx);
                minX = Math.min(minX, cx);
                maxX = Math.max(maxX, ax);
                maxX = Math.max(maxX, bx);
                maxX = Math.max(maxX, cx);
                minX = Math.max(0, Math.floor(minX));
                maxX = Math.min(size - 1, Math.ceil(maxX));
                let minY = Infinity;
                let maxY = -Infinity;
                minY = Math.min(minY, ay);
                minY = Math.min(minY, by);
                minY = Math.min(minY, cy);
                maxY = Math.max(maxY, ay);
                maxY = Math.max(maxY, by);
                maxY = Math.max(maxY, cy);
                minY = Math.max(0, Math.floor(minY));
                maxY = Math.min(size - 1, Math.ceil(maxY));
                // fill heightmap by Interpolating z values at pixel(x, y)
                for (let y = minY; y <= maxY; ++y) {
                    for (let x = minX; x <= maxX; ++x) {
                        if (isPointInTriangle(x, y, ax, ay, bx, by, cx, cy)) {
                            const aw = Math.sqrt(Math.pow(x - ax, 2) + Math.pow(y - ay, 2));
                            const bw = Math.sqrt(Math.pow(x - bx, 2) + Math.pow(y - by, 2));
                            const cw = Math.sqrt(Math.pow(x - cx, 2) + Math.pow(y - cy, 2));
                            heightmap[y][x] = (aw * az + bw * bz + cw * cz) / (aw + bw + cw);
                        }
                    }
                }
            }

I thought r_elevation is for z value, but maybe I misunderstand.

terrain
codes.zip

Error build/points-5.data

when I execute build I am not generating the data file. Not sure why. I get a 404 error that says the .data file is not found.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.