klangner / mapgen.rs

Map generator for games.
https://klangner.github.io/mapgen.rs/
Apache License 2.0
44 stars 5 forks source link

Thoughts on map extensibility #35

Closed ndarilek closed 2 years ago

ndarilek commented 3 years ago

This is a great starting point for map generation, but its limits are pretty easy to hit. I've been thinking about how to both scope this crate and make it more extensible. I've read the roguelike tutorial on which it is based, so I know that map types can easily balloon into custom filters for individual games.

It seems to me that the most important feature of this crate is whether or not a tile is "floor," open, or "wall," blocked. Other types are variations of these two.

I propose changing this to something like:

enum TileType {
    Blocked(usize),
    Open(usize),
}

And then changing all Wall instances to Blocked(0) and Floor to Open(0). Then the indices of the enum members are looked up in game-specific vecs of tile types. If I want a forest map, I'd simply create a filter that places tree tiles correctly, where the tree tile might be index 1, 8, etc. in a vec of blocked tiles.

I'm not necessarily advocating for these specific member names, but whatever is chosen should convey that a given tile is unoccupied/open/unblocked or occupied/closed/blocked. A third enum might also be useful for cases where a given tile doesn't quite fit either of these--maybe Custom. None of the existing filters would use this third member--it'd likely only be for game-specific filters.

If this works for you, I'm happy to PR it. I'm going to need this for an upcoming game, so I'll either modify and use this crate as is or fork it and port over any upstream changes you make. I'd rather work together if we can.

Thanks!

klangner commented 3 years ago

Hi, What you propose here makes sense to me.

It is true, that from this library and its algorithms point of view it is important to only distinguish between open and closed tile. So changing it to this kind of enumeration is ok. Not sure though what to do if there is third option like Custom. Since it would still have to be treated as Blocked or Open. For example some algorithms need to know if there is a path between any 2 tiles. I think Custom (like maybe doors, potions etc.) should be added as separate layer. But that rather another issue.

If you would like to change it and prepare PR with it, that would be great.

ndarilek commented 3 years ago

My thoughts are that Custom is another member that none of the filters in this crate would use. It'd only be present for situations where I wanted new filters to handle custom tiles and wrote them for my own game.

FWIW, I agree that custom things should probably be stored separately. My current map stores entities per tile in a separate index. For quickly generating something in a prototype or game jam, though, it may make sense to use the custom member and track things that way.

I'll put together a PR this week.

klangner commented 3 years ago

Regarding the Custom. Check for example: https://github.com/klangner/mapgen.rs/blob/5c440c17ba78453d4362d038060a3106432fe087/src/map.rs#L102

You can't really handle Custom tile there because it is a binary problem.

Also I would like not to go into direction where the Map structure from this lib is directly used in any game. I was rather thinking that somebody will copy the tiles data into its own structure. The reason for this is that map in the game can require many custom features and I would like to keep Map structure in this lib very basic.

Having said that I see value in your solutions since having parametrised tile types makes sense for the generators.

klangner commented 2 years ago

I guess this is done. If not just reopen with comment