2 releases
0.1.1 | May 18, 2019 |
---|---|
0.1.0 | Jan 25, 2019 |
#1101 in Game dev
70KB
1.5K
SLoC
Random World Map Generator
world-map-gen
is a CLI tool and library for Rust and WebAssembly.
It provides functionality to generate a random world map for games like a retro tactical simulation game.
A generated map consists of cells. Each cell has its altitude and kind (sea, town, plain, forest, mountain, ...).
Try it on browser by visiting project page or on your terminal by installing CLI app.
Screenshot:
Example of generated 120x120 map in 3D
Example of generated map in 2D
Example of generated map in terminal (iTerm2)
This project is my personal practice to create a Rust library which works fine as both normal Rust library and WebAssembly library, which is a bit more practical than awesome Rust+Wasm tutorial.
I leaned the algorithm to generate world maps from this small book and implemented it (with small improvements).
Installation
Try random map generation at project page
gh-page of this project is a demo page for showing how this package works. The demo site
is constructed with TypeScript, WebAssembly (thanks to wasm-pack, wasm-bindgen) and webpack.
The source code of the page is in www/
directory.
As Rust library
This library is shipped as a crate. It can be installed with cargo package manager.
Please add a dependency in your project's Cargo.toml
and run cargo build
.
world-map-gen = "0.1"
Rust compiler supporting Rust 2018 edition is necessary.
As WebAssembly library
This library built as WebAssembly is shipped as npm package.
npm install --save world-map-gen
The package contains optimized .wasm
binary, .js
JS file to glue between Wasm and JS, and .d.ts
type definition file to use this package with TypeScript.
As command line tool
Using cargo, please build CLI tool from source.
cargo install world-map-gen
It builds ~/.cargo/bin/world-map-gen
.
Usage
Rust library
Rust library provides some modules to handle a world map as one board filled up with cells.
land
:land::Land
struct represents each cell in a boardboard
:board::Board
struct represents one world map. The struct is JSON serializable withserde_json
draw
: Helper to draw a board to terminal or as JSONgen
: A random world map generator to buildboard::Board
struct. It provides algorithms for 3 kinds of resolutions; low, middle, higherror
: Error type which may be returned from a map generator
Please read the documentation for more details. And CLI code is a good live example to know the usage.
extern world_map_gen;
use world_map_gen::RandomBoardGen;
// Create generator instance with default random number generator
let mut generator = RandomBoardGen::default();
// Generate 40x40 random world map. Map resolution (low, middle, high) is automatically
// determined by its width and height here.
// - Low: width and height are less than 15
// - Middle: width and height are less than 120
// - High: Otherwise
let board = generator.gen_auto(40, 40);
// Iterate each cells per row
for (i, row) in board.rows().enumerate() {
println!("Row: {}", i);
for cell in row {
// cell is a world_map_gen::land::Land instance
// Lands are categorized with kind (e.g. Sea, Plain, Forest, Mountain, ...)
println!("Kind: {:?}", cell.kind);
// Each cell as its altitude. For example, sea's altitude is lower and mountain's is
// higher
println!("Altitude: {}", cell.altitude);
}
}
WebAssembly library
www/ directory is a good live example to show how to use this package in TypeScript and WebAssembly. It is hosted at gh-pages.
The npm package contains world_map_gen.wasm
and world_map_gen.js
. The world_map_gen.js
is an entry point. Bundler which support WebAssembly like webpack
handles the .wasm
file properly when your code imports world-map-gen
package.
import { Generator, LandKind } from 'world-map-gen';
// Generate a new random map generator
const gen = Generator.new();
// Generate random 200x200 map
const board = gen.gen(200, 200);
for (let x = 0; x < board.width(); x++) {
for (let y = 0; y < board.height(); y++) {
// Get cell of specific position
const cell = board.at(x, y);
// Get land kind like Sea, Forest, Mountain, ...
console.log('Kind:', cell.kind, 'at', x, y);
// Check the cell is town
console.log(' town?:', cell.kind === LandKind.Town);
// Get altitude of the cell
console.log(' Altitude:', cell.altitude);
// Get color code of the cell as #rrggbb format
console.log(' Color:', cell.color_code());
// Get land legend
console.log(' Legend:', cell.legend());
}
}
// Get JSON representation of board
console.log(JSON.parse(board.as_json()))
Let's say this code is put as a file index.js
.
As the entry point of your application, please ensure to use dynamic import.
It is necessary because all .wasm
code must be imported asynchronously.
import("./index")
.catch(e => console.error("Error importing `index.js`:", e));
world-map-gen
package also contains world_map_gen.d.ts
for working with TypeScript. You don't
need to write type definitions of APIs. TypeScript compiler automatically detects the .d.ts
file.
Please ensure to use esNext
for module resolution of TypeScript compiler. It translates
TypeScript's import statements into ES Modules and webpack will handle them later.
{
"compilerOptions": {
"module": "esNext",
// ...
},
// ...
}
CLI tool
Please read world-map-gen --help
output to know the interface.
Each cell is represented with ██. And ANSI 256 colors are used for cell colors. Some terminal may not work properly. I'm testing this CLI tool on iTerm2.
By default, it gets terminal's width and height and uses entire terminal screen to show map.
You may need to make font size smaller temporarily to show larger maps. Map's resolution is
automatically determined from width and height by default. And you can specify them by command line
options. And --json
outputs a randomly generated map as JSON.
USAGE:
world-map-gen [FLAGS] [OPTIONS]
FLAGS:
-a, --altitude Show altitude instead of squre as cell mainly for debug
--help Prints help information
-j, --json Output JSON-serialized result to stdout
-V, --version Prints version information
OPTIONS:
-h, --height <INTEGER> Board height in number of cells
-r, --resolution <STRING> Resolution of world map [possible values: low, middle, high]
-s, --seed <INTEGER> Seed for random number generator
-w, --width <INTEGER> Board width in number of cells
Development
Makefile provides useful scripts to develop this repository.
For debugging Wasm package from browser, please build this package with wasm-pack and
--features wasm_debug
.
License
Distributed under the MIT License.
Dependencies
~2–12MB
~140K SLoC