Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding in logic to work with rot.js Cellular type maps #12

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

ratacat
Copy link

@ratacat ratacat commented Dec 30, 2018

This adds in logic to work for Cellular type map parameters

Which you can set when calling Axolemma.generate
passes = 6 //number of passes to run the Cellular growth algorithm
randomize = .54 //number between 0 and 1 for the chance of each room starting out with a 'cell'

This doesn't account for several additional Cellular type parameters, I'd like to incorporate later.
born:
survive:
topology:

Copy link
Owner

@seanohue seanohue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume, though, that "randomize" is simply passed in via mapperOptions?

map.create(mapper)
if (type == "Cellular") {
mapper.randomize(randomize);
for (var i=0; i<passes; i++) map.create(mapper);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear where 'passes' would be defined -- it seems like this would always be undefined, and potentially, would just overwrite the map each time it is ran anyway.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was passing it in through Axolemma.generate. I'm not sure that makes the most sense, but it seemed to work!

`/ Require-able like any other library.
const Axolemma = require('axolemma')

const {manifest, graphic, rooms, yaml} = Axolemma.generate({ // Programmatically pass in options
type: 'Cellular', // Uses ROT-js well-documented map generation algorithms.
width: 150,
height: 100,
randomize: .46,
passes: 10,
writeToFile: true, // Can write YAML definitions to file for static persistence
weightedRoomsTable: require('./rooms-table')
})

// Returns YAML string.
//console.log(yaml)

// Returns an old-school ASCII map of your area.
console.log(graphic)

// Returns area manifest as JS object.
//console.log(manifest)

// Returns Ranvier-compatible room definitions.
//const newRooms = rooms.map(
// roomDef => new Room(roomDef)
//);`

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may have been working by a fluke -- passes would be undefined since we're not destructuring it from the options object (based on the commits in this PR, anyway).

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, wouldn't iterating over passes like that cause the map to be totally regenerated each time?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

http://ondras.github.io/rot.js/manual/#map/cellular

Looking at how this example is implemented, I can see where you're coming from but I think this may require more changes inside of map.create for it to truly create the nth generation.

That said, I haven't actually touched Axolemma in months, so I plan on digging into this PR more soon. Overall it is a good start at the very least, and would be cool to support.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot to pass the parameters along to the options and mapper options. Maybe that was part of the confusion. As for repeatedly calling mapper.create, look at rot.js map.Cellular.prototype.create

ROT.Map.Cellular.prototype.create = function(callback) {
	var newMap = this._fillMap(0);
	var born = this._options.born;
	var survive = this._options.survive;


	for (var j=0;j<this._height;j++) {
		var widthStep = 1;
		var widthStart = 0;
		if (this._options.topology == 6) {
			widthStep = 2;
			widthStart = j%2;
		}

		for (var i=widthStart; i<this._width; i+=widthStep) {
			var cur = this._map[i][j];
			var ncount = this._getNeighbors(i, j);

			if (cur && survive.indexOf(ncount) != -1) { /* survive */
				newMap[i][j] = 1;
			} else if (!cur && born.indexOf(ncount) != -1) { /* born */
				newMap[i][j] = 1;
			}
		}
	}

	this._map = newMap;
	callback && this._serviceCallback(callback);
};

specifically newMap and this._map at the bottom near the survive and born logic. It saves the state in the mapper instance, and updates it for each time it's called.

It's working for me at any rate...and doesn't seem to break the other modes

...................................#
.....#.......#####.#.........#.....#
............#######...........##...#
............#..###............#####.
............#.................######
............####.......##.....######
.............###.......##......###.#
............###.........##......####
...........#####.........##......###
.........#######..........#......###
.....########.###........##.........
...#####.###...#........###.........
.....#.....##.#####....####.........
....#.......########..######........
.............######.....####........
...............####......###.......#
................###........#.......#
...#.............###.............#..
...##............###.............#..
.................###................
..................#.................
....................................

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also yeah, I have only been playing at it with require in a 'staging' file...haven't really done anything with CLI or ingame command.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ratacat Thanks for both clarifying and adding the missing pieces!

Great work.

I'll merge this in sometime this week and test it out on my own. At some point in the future, one of us or another ambitious contributor could add it to the CLI and flesh it out.

Thanks again!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realized that the weightedCreation callback function which creates the rooms, gets called once for every pass, even though it doesn't need to create the rooms until after all the passes are complete. I'm looking at the best way to address that. It works fine obviously, but is wasteful.

Also, I'm currently working on a modification to use a custom mapper (based on Rot.js cellular), but which allows you to apply similar evolutionary algorithms to a map that uses multiple terrain types.

So you could grow a map with forests, swamps, mountains, hills, lakes, grasslands...etc. Currently just focusing on implementing each 'type' with the cellular automata growMethod. But it should be easy to plug in different growMethods, ones that could work for roads, rivers...etc

@seanohue
Copy link
Owner

Also, it seems like this means that the Cellular type would only be usable via requireing axolemma, and not the CLI -- this is fine and CLI support for it can be added later, or I could walk you through how to do that.

passes,
born = [5, 6, 7, 8],
survive = [4, 5, 6, 7, 8],
topology= 8
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't mind, fix the formatting here please. I can also make this change sometime soon.

passes,
born = [5, 6, 7, 8],
survive = [4, 5, 6, 7, 8],
topology= 8
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants