amethyst / rustrogueliketutorial

Roguelike Tutorial in Rust - using RLTK
MIT License
901 stars 156 forks source link

4.3: BSP is ... not a BSP? #156

Open abesto opened 3 years ago

abesto commented 3 years ago

(Still) having an awesome time following along the tutorial, thank you so much for writing it!

Section 4.3 got me confused. For context: I've heard of BSP before, but never implemented one / looked at it very closely.

The first thing that confused me was that the "B" in BSP stands for "binary", but the algorithm in the tutorial seems to subdivide each region into 4 parts, so this would be more like ... quaternary? Given that confusion, I did some quick searching and read http://www.roguebasin.com/index.php?title=Basic_BSP_Dungeon_generation. Based on that, there seem to be (at least) two major differences between the algorithm in 4.3 and BSP as described on roguebasin:

I'm pretty new to procedural generation, so first, a question: do I just have a too-narrow idea of what BSP is? If not, it may be good to note how exactly the algorithm given deviates from "canonical" BSP. And second: I've directly implemented the roguebasin flavor of BSP at https://github.com/abesto/rktrl/blob/f923a14d1f00216f807768c43c402fa5e11d91b4/src/mapgen/bsp_dungeon.rs within the framework set up by the previous chapters. If useful, feel free to use / share.

bsp

abesto commented 3 years ago

Addendum: the BSP implementation above (which, yes, I forget the stairs, obviously) was somewhat easy to make configurable, such that the exact same map builder, given different inputs, can generate either a dungeon or a castle interior (as in chapter 4.4):

impl BspConfig {
    pub fn dungeon() -> Self {
        BspConfig {
            subdivision_variance: 0.2,
            depth: 6,
            min_room_width: 6,
            max_room_width: 10,
            min_room_height: 6,
            max_room_height: 10,
            max_padding: 9000, // Arbitrarily large number. Not maxint because that leads to overflow.
            min_padding: 2,
        }
    }

    pub fn interior() -> Self {
        BspConfig {
            subdivision_variance: 0.2,
            depth: 5,
            min_room_width: 6,
            max_room_width: 9000,
            min_room_height: 6,
            max_room_height: 9000,
            max_padding: 0, // this is what gives us the "interior" look
            min_padding: 0,
        }
    }
// ... SNIP ...
}

Implementation: https://github.com/abesto/rktrl/blob/4360f791e930679ae7f46896916703c7104772d0/src/mapgen/bsp_dungeon.rs

bsp-interior.gif