-
Notifications
You must be signed in to change notification settings - Fork 1
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
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this 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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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)
//);`
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
...................................#
.....#.......#####.#.........#.....#
............#######...........##...#
............#..###............#####.
............#.................######
............####.......##.....######
.............###.......##......###.#
............###.........##......####
...........#####.........##......###
.........#######..........#......###
.....########.###........##.........
...#####.###...#........###.........
.....#.....##.#####....####.........
....#.......########..######........
.............######.....####........
...............####......###.......#
................###........#.......#
...#.............###.............#..
...##............###.............#..
.................###................
..................#.................
....................................
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
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
Also, it seems like this means that the Cellular type would only be usable via |
passes, | ||
born = [5, 6, 7, 8], | ||
survive = [4, 5, 6, 7, 8], | ||
topology= 8 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
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: