Version 0.2 Update
It’s been a while! There are a couple reasons for that, but the most exciting is that my son was born on August 8th, 2016! So I’ve been a bit sleep deprived, but me and my wife are very happy.
The other reason is that procedurally generating houses the way that I decided to do it was rather difficult. However, barring a couple improvements that need to be made regarding how they are oriented on their ‘lot’, it’s done! I’ve also made an algorithmic discovery for improving how I’m generating office buildings. I’d like to devote an article each to the details of those algorithms, and I might try to make them available on RogueBasin and the PCG wiki. However, a brief summary of my work will be detailed below:
Office Building Improvements
The way I generate office buildings is like so:
- Draw a rectangle
- Place a staircase in a corner
- Bisect the rectangle vertically and horizontally a few times to create smaller rectangular rooms inside the ‘outer wall’
- Draw a door on the outer wall for access
- Perform a poly-fill on the tiles in order to find distinct rooms, and place a single door between the walls so the whole building is accessible
This works. However, what this means is that every room has a door to all it’s neigbors. This isn’t totally realistic or fun, and I thought for sure there would be a way to use my poly-fill technique to intelligently place doors such that not every room has a door to all it’s neigbors, but that it is possible to access every room through a particular path from any other room. The good news is that I found a solution!
The short version is that when I perform my poly-fill, I assign a number to every room. Room 1 will be adjacent to room 2, 3, and 4. Room 3 might be adajcent to room 5, 6, and 7, and room 5 might be adjacent to room 8 etc. If you place a door between the rooms that have the greatest difference, you get a consistent path through all the rooms without needing a door in every wall. I have no idea why this works, but it does.
I still need to implement this in the code, but I thought it was cool. I’ll write a more detailed post some time in the future.
Houses
I ended up taking a completely different approach to generating houses, and it’s based largely off of this article.
I’m rather proud of the algorithm I wrote for generating houses. It’s an application of a lot of theoritical concepts, and it feels a bit more academic that I’m used to while programming. There are two big steps that generating houses follows, and again, I’ll probably write a bigger article about just this to outline more technical details:
- Procedurally generate a graph based off of a grammar I’ve defined that determines which rooms can connect to other rooms (bedrooms can connect to closets, halls and bathrooms, but not kitchens etc.)
- Using this graph, recurrsively render each room and then it’s children, ‘spawning’ these rooms in a random cardinal direction based off of a ‘house facing’ direction. When a room cannot be rendered due to an existing room pressing into it’s space, or if the room would exceed the house’s max-width or max-height, add the room on the next z-level.
I’m really pleased with the result! There were several challenges that I needed to overcome: when placing a room in a random direction, because tiles are organized in a 3 dimensional array such that tiles[z][x][y] == tile
, it’s really tricky to account for adding tiles ‘north’ or ‘west’ of 0 (the first element of the array). I also created a bug where I was trying to place stairs as I was spawning rooms, and because of the way that I have to shift the tiles around when adding rooms north or west, the stairs would get slid out of sync with each other so that going up stairs would place you on a tile with no down stairs, or in a wall or sometimes out in space. No I place stairs once after the whole house has been rendered.
What’s Next
Furniture and Items
I need a break from all this PCG business with buildings, so I’m going to tackle items. The framework is already there, and I think it makes the most sense to use mixins instead of a completely new prototype. I may change my mind as I start working on it. What I want to have initially are some decorative tiles like statues, more functional (though I don’t know their mechanical function yet) things like beds, chairs, tables, and also something I’m calling “job items” which are things like cash registers, desks, toolboxes and things that NPCs (and maybe the player) path to for their jobs, and once they are within range of these items they can perform their job action which will earn them some money. Beds might also fall into the category of a ‘job item’, since when it’s time to sleep, they will have to path to it to perform that ‘job.’ I’m at least 60% sure this is how I want to handle this…
Skyscrapers, Apartments and Parks
The other lots I am wanting to write PCG for are skyscrapers, apartments and parks. Skyscrapers will basically be almost-full lot-sized buildings, but I think it would be fun to incorporate a little bit of a special shape randomization on the outer wall of these skyscrapers: circles, ovals, octagonal etc. I don’t know how technically how best to do this, and I don’t know if it will be too hard for such a non-impressive thing, but we’ll see.
Apartments on the other hand I’m thinking might benefit from a template system. In fact, a templating system in general might be useful in a lot of circumstances.
Parks may or may not happen, but they’ll probably just have some benches and maybe a fountain or two, and would mainly just be an alternate to an empty lot; a place that I don’t want to have buildings but could potentially be a point of interest.