Saturday, April 27, 2024

City Overhead Walkways

I'm always looking for ways to connect buildings and city areas together. Last year I added underground hallways to connect the basements of different houses into a maze of underground passageways. This time I've added overhead walkways to connect nearby city office buildings.

Walkway Exteriors

Walkways are added just after buildings are placed in cities, but before city objects are placed on the ground below. The first step is to select candidate buildings for walkways, which are currently limited to non-rotated cube-shaped windowless office buildings. For each building, all nearby buildings within 1.5x the length of the building are considered and marked as connection candidates if they're compatible, meaning they have a cube shape and the same vertical floor spacing. The 1.5x length factor is long enough for walkways to span roads, but not long enough for them to cross an entire city block. This is important because we don't want to be adding walkways across the sky in parks.

For each pair of buildings, all opposing exterior walls with shared height ranges and perpendicular projections (overlaps) of at least twice a doorway width are considered. This guarantees the walkway can connect two opposite rooms at least one floor tall and wide enough to add doors at each end with a straight segment. If the overlap area is larger than the minimum, a random horizontal position, width, and starting floor are selected. The height each walkway is selected to be between one and three floors. At most one walkway can connect between each pair of buildings.

Walkways have a "parent" building that technically owns it, and a second "connected" building. They inherit their top and bottom surface textures and colors from their parent. They use their parent's side wall texture as well, but only for the building materials flagged as walkway compatible. This includes the office building textures, but not the apartment and metal buildings because those window styles look wrong on walkways. When neither connected building has a compatible side texture, a random texture is selected from among the valid set. This system makes the walkways blend into the building exteriors relatively well.

Some of the longer walkways have one or more vertical supports made from either vertical concrete rectangles or steel cylinders. These are placed at the center of the span if valid (not blocking a road, sidewalk, or building). If the center isn't available, locations to either side of the center are considered. Support pillars are optional.

Here are two example screenshots of city walkways between buildings, viewed from above. I have cars and pedestrians disabled in some of these screenshots to reduce the number of distractions from my newly added content.

Exterior view of walkways connecting city buildings. The near walkway is one floor tall, while the far walkway is too floors tall.

Another view of building walkways, this time with cars and pedestrians enabled.

One of the important questions I had to answer was who owns these walkways, the city system or the buildings system? After some failed experiments, I decided that the answer had to be both. The city owns the exterior part of the walkway, and the parent building owns the interior. This solves a number of problems.

Since the city owns the exterior, it can check for collisions of tall objects such as trees and flag poles with the bottom of the walkways. The simplest solution is to block off the areas under low walkways and avoid placing tall objects there. It can also check for bird collisions. One final requirement is to limit the elevation of walkways crossing roads to be at least several floors high so that they clear the tops of the telephone poles.

I implemented player collision detection with both the interior floor(s) of the walkways and their roofs. This allows the player to both enter them and walk inside, and walk along the roof from building to building.

Walkway Doors

Since the building owns the walkway interior, we can make this a building extension similar to extended basement connector rooms. This allows doors to be placed at either end, interior walls/ceilings/floors to be drawn, and the player to walk inside it.

Walkways are currently added after building interiors are generated, but before rooms are assigned a function or any interior objects are added. This means that the walkway doors must be placed in a way that avoids intersecting interior walls, stairs, and elevators. Checking for walls is relatively easy. All rooms are at least several doorway widths in length, and the walkway is at least two doorway widths. We should be guaranteed to have some location along each end of the walkway that connects to a room in the adjacent building without hitting a wall. I added code to shift the doorway to the left and right when a wall is encountered, and stop when the door no longer intersects the wall.

Stairs were more difficult to handle. Sometimes stairs that run perpendicular to the walkway block the entire end so that a door can't be placed anywhere that doesn't intersect the stairs. I've seen this happen for exactly one building/walkway pair. Maybe I should reorder the placement steps so that walkways are added before stairs? It seems like a lot of effort to fix one failing case. So instead I simply don't place a door at that end, and the walkway interior remains unconnected to the adjacent building.

There's one more constraint to handle. It doesn't make sense to have walkways connect to private rooms such as bathrooms. When this happens, the room is re-assigned to be another type, such as an office. Larger office buildings generally have one or more bathroom per floor, and walkways only span 1-3 floors, so there are plenty of alternative bathrooms for the employees and visitors to use. If I omit this check, this results in cases such as the one shown below.

Failed placement of a "secret" walkway door that opens into a bathroom stall. (This is from earlier in development when I was using house doors rather than office building doors.)

Here we have a door that opens into a bathroom stall. Actually, I'm not sure if the door can really open with the toilet and stall in the way. How's that for bathroom privacy? I can modify the stall placement to leave this area empty, but that would still look very wrong. What happens when a man walks through the women's restroom to use the walkway? Do I need to make a Men's vs. Women's walkway?

Ideally, doors should connect to main hallways, but that's not always possible within a narrow shared segment of the building wall. I'm allowing walkways to connect to other room types such as offices for now. Maybe this doesn't make a whole lot of sense, but it was the easiest solution. In cases where the walkway is wide enough that the door can connect to multiple rooms, hallways are preferred. Of course we still need to check for objects such as desks, tables, and whiteboards that may block walkway doors and relocate them along a different room wall. And we can't forget light switches and electrical outlets.

I used the same exterior office building doors for walkway entrances from buildings. These open to the sides automatically as the player passes through. The only issue I haven't solved is lighting of exterior doors on the walkway side, since they don't receive room lighting and the sun and moon lights are shadowed by the walkway itself. For now they look too dark.

Walkway Interiors

At first I couldn't figure out how to add ceiling lights since walkways aren't real rooms of the parent building. Instead, I cut windows into the interior sides and increased the ambient light levels to let the sunlight in. There are no windows cut into the exterior sides of the walls though because it's not easy to line them up with the outside wall texture. Some of the textures don't have evenly spaced windows. This is the same reason I don't have windows cut into the buildings themselves. Just think of the windows as being one way mirrors, except that they don't actually have reflections. I haven't yet figured out how to enable sun shadows through the one-way windows.

I definitely like how the windows turned out. The player can look out over the city and understand that they're in a real physical walkway. This slightly makes up for the lack of windows in the office buildings themselves.

I was eventually able to hack the code in all the right places to make ceiling lights work properly. The light bounds calculation must use the walkway rather than the room bounds, among other changes. The player can't interact with these lights, and there are no light switches, but they do illuminate the interior hallways. This is important for night time when the sun is gone and ambient light levels are low.

View from inside a building walkway that crosses the road, looking out a window at the city.

Here are two more screenshots of a very long walkway and a very short walkway. Long walkways are used to connect buildings in different city blocks, while short walkways connect nearby buildings within the same block.

Entering a long building walkway.


Entering a short walkway between nearby buildings.

At some point I realized that all the carpet textures were the same. I fixed this by adding a mix of the three office building carpet textures for variety. These are the same set of textures used in the buildings themselves.

Long, narrow walkway.

Night time view out the walkway window, with pedestrians, cars, and light bloom enabled. Sorry, indirect lighting is not yet working for walkway interiors.

Adding walkways took significant effort, but not nearly as much as connecting the extended basements of houses. This is partly because people, zombies, and animals can't use these walkways. The player also can't use spray paint, throw balls, drop items, or otherwise interact with walkway interiors. I may go back and implement some of this in the future. It's not clear that this is needed for gameplay. In fact I wasn't originally planning to have zombie gameplay in commercial cities because these huge windowless office buildings aren't as fun for gameplay as the smaller buildings. It's too easy to get lost and to lose a zombie that's giving chase. Also, it's inconvenient to repeatedly find the exit door when your inventory is full.