Monday, May 8, 2023

Procedural Buildings: Connecting Basements

Some of the houses in 3DWorld have extended basements consisting of a maze-like tree of underground hallways and rooms. These can run under the house and nearby buildings, as long as no other buildings are intersected. I like these mazes. I like anything involving underground networks to explore where the player can get lost, in particular in a horror game setting. The current limited size of each house's extended basement prevents me from adding larger mazes. It's not just a problem with available space, it's also a problem with reduced performance when adding too many rooms to a house or making it's bounding cube too large. The various building view culling methods I'm using are less effective when many buildings overlap in 3D space.

One workaround for this is to allow basements to connect between multiple houses. In fact, they can connect together in a massive dungeon maze that runs under the entire residential neighborhood. This case is made easier because all houses are at the same elevation, so I don't even need to add stairs to connect rooms at different levels. I decided to start by grouping houses by city, and attempting to connect each house in the city to every other house placed after it. This is quadratic in runtime, though only for a few hundred houses at a time since they don't all have extended basements. The final runtime for this step was only 19ms for all four residential cities combined. I didn't even have to make the code multi-threaded.

If two nearby rooms that project in X or Y can be found for each of these houses, a new hallway room is added to connect them. I cut a hole in one of each of the room's walls to insert a door. I placed a red light on the ceiling of this room to make it stand out more. This way I can find and debug connector rooms by disabling collision detection and flying below the ground looking upward for the red lights. I'm glad I added this for debugging because I certainly found a lot of problems with this system! Every room had some new bug. I'm sure I haven't found and fixed them all yet.

The only downside is that this was very complex and difficult to get right. Not only does it need to look correct, but the AI and physics must work as well. On the visuals side, I had to make sure the occlusion culling didn't flag the other house as invisible as it normally does with other buildings when the player is underground. Then I had to work out the lighting and shadows so that the connector room could cast and receive both light and shadows from the rooms of the two houses that connected on either end. These had to be updated when the user toggled the lights or opened/closed the door from either side. In addition, the ambient lighting system had to consider light coming through the open connector door.

Physics was also quite challenging. I had to update the player collision detection to allow walking between buildings without being blocked by the basement bounding cube, and without the player being considered outside a building for one frame and popping out of the building on the ground above. This last problem took me many attempts to fix! In fact, I think it can still happen in rare occasions when a building person or zombie pushes the player into a wall near the connector room.

Players had to be able to open or close the connector room doors from either side, which means I had to support interacting with a door belonging to a different building from the one the player was inside. Next, I had to allow the player to carry inventory items between buildings without them being deposited in the player's permanent loot collection as would normally happen when exiting a building. Building animals and people AI were updated to handle these connector rooms. I didn't quite figure out how to have them cross between buildings, but at least they don't get stuck there. Zombies will follow the player right up to the connecting door and wait for a few seconds before walking off. This provides the player with an escape route. I think that's fair because it's far too easy to get cornered or lost while being chased in a basement maze. However, chances are some zombie in the other building heard you and is on the way to find you.

Probably the most difficult feature was adding support for basketballs and soccer balls that could be rolled, kicked, or thrown through the doorway into the next building. These objects have physics state owned by their contained building. I had to transfer this state from one building to another in a way that preserved the properties such as position, velocity, and momentum. There were various special cases to handle. For example, the player can stand in one building while holding the ball through the doorway into the other building. The physics must be seamless across the boundary.

Here are some examples of extended basement connector rooms.

Extended basement connector hallway with red light, a picture on the wall, and a rug on the floor.

Hallway connecting one house basement to an underground storage room in a different house.

Room connecting two house basements. You can tell that the connector room belongs to the building the player is in because the carpet matches.

They look very similar, especially with the red lights. At the moment this is a somewhat intentional way to let the player know they're passing between buildings. There's also a "Welcome to <NAME> Residence" text to let the player know whose house they're entering. Maybe I should select a random light color from a list of colors? I'm not sure. I experimented with different colors and I definitely like red the best because it produces a sense of danger and has a good contrast with the off-white color of other ceiling lights.

What's next? Maybe I'll figure out how to have people and animals cross between buildings. Maybe I'll connect office building basements and parking garages in a similar way. There are so many possibilities...

6 comments:

  1. Nothing much to say, but I really like the red corridor connections! (srt19170)

    ReplyDelete
  2. Can't wait to play the game amazing work and thanks for the development insights!🙂

    ReplyDelete
    Replies
    1. Thanks! At this point it's not really a game yet, but more of a tech demo.

      Delete
  3. Very neat! I'm wondering though, would it be possible to make the basements not spatially local? Like, have the connectors go to basements that are far away, so you could use the basement labrynth as a rapid transport network? I know you're using render masks for the windows. Could you do the same thing to make portals? Or, I seem to recall you made portals already?

    It also seems strange that cities and suburbs are totally flat and level. Could you subdivide the cities into districts?

    ReplyDelete
    Replies
    1. I added teleporters in a previous post, but they work differently and are done in "ground/gameplay" mode rather than this which is "infinite terrain mode". In theory it would be possible, but I'm not sure it's necessary. I already have instant travel to a selected location supported in overhead map mode. This is great for debugging problems with buildings that are far from the starting location (and more convenient than moving the starting location in the scene config file).

      These flat cities are more like sub-cities. A flat terrain makes everything much easier. I do have other areas outside the city where the terrain is hilly, but the buildings aren't placed very realistically and the roads don't connect to every building. I used these flat areas for connecting basements because it guaranteed their elevations matched without needing to add some sort of weird partial staircase.

      Delete