Tuesday, January 19, 2021

Procedural Buildings: Gameplay Ideas

High Level Goals

I've been thinking about the end goal of 3DWorld's procedural city and buildings system. I feel like this is still many years away, and I have lots of crazy ideas that will take hundreds or thousands of hours to implement. I really plan to make procedural cities and buildings only a small part of the overall procedural universe.

The long term goal is to have a set of galaxies with solar systems, stars, planets, and moons. The player can land on each planet and moon, and these can contain various biomes with vegetation, cities, etc. depending on their parameters (radius, temperature, atmosphere, amount of water). Each city will have buildings, road networks, vehicles, people, etc. I want to have land vehicles, air vehicles, and water vehicles. People (or some type of sentient organism/being) will be in the vehicles, in the buildings, on the sidewalks, and walking on the terrain.

I actually have most of these individual pieces by now. I have the universe/galaxy/solar system/star/planet/moon code in my universe mode with its own ship battle gameplay. I have limited cities with a grid of roads, where each city is connected to its neighbors by longer roads. I have cars, trucks, and helicopters. I have people on city sidewalks and inside buildings. I also have buildings with full interiors in both the city blocks and surrounding suburbs. These are a mix of houses, small commercial office buildings, and larger office towers. I have procedural terrain with a generated heightmap, erosion, water, grass, trees, and plants. What I'm missing are all the pieces to tie these different parts together, plus many bits of missing functionality. For example, I have yet to add roads connecting secondary buildings and people in cars. I also don't have a continuous transition from space to heightmap terrain.

Gameplay Ideas

Anyway, that's all a long way off. Right now I plan to add some type of incremental gameplay with these procedural buildings. I want to keep it relatively simple and try to use as much existing code as possible without having to implement many new large systems. That means it has to be done with the existing cities, buildings, cars, and people, plus whatever incremental additions are needed. I prefer to have more of an open world game, so that means it should use the secondary buildings rather than being constrained to the smaller gridded city blocks. That also means I can take advantage of the higher detail and better window placement/drawing of the smaller buildings.

I'm not too interested in the difficulties of multiplayer gameplay, and I have no idea who I would play against. Therefore, it should be a single player game. The existing people I have in buildings can be the enemies, since they already have a basic AI that can navigate the building and find the player. I was leaning towards making those people zombies so that I can get away with their current state of poor AI and poor animation. It's much more forgivable to have a zombie (rather than a normal person) running into walls, getting stuck on furniture, taking the long way around, and only moving their legs. I prefer not to write a complex animation system. Maybe if I can put their arms out in front rather than having their arms in the T-pose that would look okay.

My goal is to have some sort of open world game where the player is encouraged to explore the buildings with some form of excitement. Maybe I can have it be some type of survival game where the player collects food from refrigerators and bottles from the tables/desks/counters to drink. I can add some secondary goals such as collecting items from desk and dresser drawers, or maybe rescuing people. Item collection could be in the form of robbing the house of valuables, something like breaking-and-entering mixed with zombies. I can't say I've ever played or seen a game like that before. The player must complete these tasks while zombies are trying to catch and infect them. I can also add other damage types such as fall damage from the roof, stairwells, and elevator shafts.

Zombies track the player based on a combination of sight and sound. They'll wander around the building randomly until they either see or hear the player, then they'll converge on the player's location. One touch from a zombie and it's game over. Or maybe there's some chance of pushing the zombie away, with a cool down timer. The idea is to keep the player moving and force them to pay attention and avoid getting surrounded or trapped in a dead end room. The more time spent in any one building, the more dangerous it gets. It's up to the player to know when to give up searching and make a run for the exit. I'm not sure if I'll add dangers out in the open between buildings.

I haven't yet decided if I want the game to be funny, scary, or a bit of both. I'll just have to experiment to see what I like best. I don't plan on adding combat with zombies or any sort of violence. This is a survival + stealth + run-and-hide game, not a combat game or shooter. The goal is to outsmart the zombie hoard rather than defeat it.

Gameplay Details

Here are some details for how gameplay may work. This is the first draft and is subject to change. The player can control building lights, close and lock doors, use elevators, and create distractions.

Lights: Room lights start randomly on or off. The player can only search a room for items when the lights are on. However, zombies can see the player from a greater distance if the lights are on, or maybe if the player is lit by at least one light (not fully in shadow). Zombies will also be attracted to the area if they see a light switch on or off. The player can also have a flashlight that can be use for a limited amount of time and has less of an effect on zombies. The player can only inspect items in their flashlight beam, but zombies will react with rage when the flashlight beam hits them.

Doors: Most interior building doors start open. The player can close doors at any time. Closed doors block line-of-sight for zombies and make it easier for a player to sneak around. Closed doors muffle sounds behind them. They also stop zombies for a few seconds while they figure out how to open doors, making this an effective way to slow them down. However, opening and closing doors will make noise that draws the attention of nearby zombies. So it's a choice the player has to make. I would also like to add the ability for the player to lock doors. This takes some time, maybe a few seconds. It will them slow zombies down as they take time to break through. Once a door is broken it can no longer be locked. But be careful - it takes a few seconds to unlock a locked door, so you better not accidentally lock the door to your escape route!

Closets: Closets have doors that can be opened and closed as well and act like tiny dark rooms. The player can enter the closet and hide there. Zombies will rarely look in closets, unless they see a player enter one. But be careful, there's no way to see what's outside. Maybe a zombie is standing right outside the closet door!

Noises: Zombies can hear player movements from a distance that depends on the sound level. Opening and closing doors makes a lot of noise and can be heard from far away. Opening and closing drawers makes somewhat less noise. Picking up items make a bit of noise, and even walking makes a small amount of noise that can be heard by a zombie in the same room. Standing still is the only way to be completely quiet.

Distractions: The player can pick up items they find such as the existing books and bottles I have scattered around on tables, desks, and counters. These go into one or more inventory slot(s). Then they can be thrown into a room to make a noise that distracts nearby zombies. Need a quick exit? Throw a bottle to the end of the hallway opposite the exit door.

Elevators: The player can use an elevator if it's stopped on the correct floor and they avoid falling down the elevator shaft. Zombies can't use elevators. This is a good escape route for office buildings. I'm not sure if I want to allow zombies to fall down the elevator shaft after the player.

I think those items could make for some pretty fun and interesting gameplay.

Keep in mind that zombies are relatively slow compared to the player, maybe half the player's speed. They're easy to outrun (and lose) if you know where you're going and don't get stuck. They're still dangerous in a variety of situations:

  • When you're not paying attention while searching and a zombie sneaks up behind you
  • When a zombie corners you in a dead end room with no exit to escape through
  • When multiple zombies approach from different sides and you have nowhere to run or hide
  • When you turn the corner or open a door and run into a zombie

Code Additions

The good news is that I have almost all of the code setup to do this. Building exteriors and interiors should be complete enough for gameplay. The player almost never gets stuck, and 95% of buildings should be fully accessible (all rooms can be reached). The AI I have for people may already be sufficient for zombies. I have the random walking and logic to have them converge to a particular location or room. That allows them to navigate to the location of a sound and follow the player. I already have items such as bottles, books, and office supplies that can be collected or thrown as distractions.

I just recently added sounds for light switches, door opening and closing, and walking. I can add sounds for zombies as well. The door and light switch sounds can easily be hooked into the AI alert logic to have them converge on the source of the sound.

I already have a key command that the player can use to switch on and off both ceiling lights and lamps in rooms. This affects the ambient light level in the room. I have light ray casting setup so that it should be easy to tell if the player is lit vs. in shadow. AI people can also turn lights on when entering a room, and similarly turn the lights off if they're the last person to leave the room. I don't expect zombies to turn lights on or off though - they just don't care.

Exterior doors automatically open and close when the player enters and leaves the building. I just recently added the ability for players to open and close interior doors. There's a new open_probability parameter that will control what percentage of doors are initially open, and I plan to keep it near 1.0 (100%). When closed, the door acts as a collider to block both the player and other AI people inside the building. I should be able to do a visibility ray cast that handles doors as well. The AI path finding/navigation system understands closed doors and has a flag that can either tell the person to go around or open the door and walk through.

The player can also already open closet doors and enter closets. I haven't worked out the logic for what happens if they close the closet door and lock themselves inside yet. I'll have to make the closet dark inside so that the player must use their flashlight to look around.

It might be interesting to add basements to houses. These work like normal floors, except they have different room type assignments with different objects and no windows. The lack of windows means that they're extra dark, to the point where the player can't see where they're going without a room light or flashlight. One difficulty of basements is that they're below terrain level, so I'm not sure how I can make that work in the current buildings system.

Finally, I already have tiled terrain mode hooked into the existing ground mode gameplay system with a health bar, fall damage, death tracking, etc. I have onscreen text and bar displays for all of this. And I have collision detection with people implemented. Those are some of the core components needed for gameplay.

Summary

That's almost all I need for this proposed game. I just need to implement the item collection system, hunger, thirst, stamina, etc. meters, the high-level gameplay logic, inventory system, zombie activation logic, etc. It shouldn't take too long to complete all of this as these are all incremental tasks. Of course I'll probably get distracted by trying to fix dozens of other things in the process. Hopefully this won't put me too far out of the way for reaching my longer term goals.

Sorry, there were no screenshots or videos in this post. I'm just doing some thinking. At least it's not very technical. I'll continue with plenty of screenshots next time.


Thursday, January 7, 2021

Helicopters

Finally, a post that's not about procedural building interiors! I added helicopters to 3DWorld's procedural cities environment. It started out simple, and I just kept adding to it like I did with cars. For some reason, I can't stop myself from adding more features. This one was 90% fun and only 10% frustration though as I was able to get most of the features to work pretty quickly.

At first I added helipads to the roofs of some of the larger/taller city buildings. But what good are helipads without helicopters? I had to add them next. I started with one 3D model, but that wasn't enough, I had to make it support multiple models and ended up with two of them. Stationary helicopters aren't so interesting, let me make them fly. They can't just fly anywhere though, they need to choose an unused destination helipad on some other building in some other city. Right, they also need to slowly take off and land, and rotate into the correct orientation in the process. Okay, so now helicopters fly around, that's pretty cool. But wait, they're colliding with buildings! Let me add collision avoidance for buildings and terrain by increasing their altitude to avoid these objects.

That's better, but they need to cast shadows on the buildings and ground. Soft shadows. They need to self-shadow themselves as well. Okay, it was a lot of work to make shadow updates efficient. Oh, wait, the blades need to rotate too. (Or is propeller the correct term here?) The shadows need to show the rotating blades. There, that's more like it. That took, what, only two weeks to add and a few hundred lines of code?

Here's a screenshot of my first helicopter model sitting on the helipad on a building roof.

Helicopter resting on a helipad, casting a soft shadow.

Fortunately, helicopters were much easier to add than cars. Cars took me months of working an hour a day at night to finally complete them. There are several factors that account for the difference. First, I already had all of the 3D model loading and drawing systems for cars that I could reuse. Second, there are only 30 helicopters compared to ~4,000 moving cars, which means I don't have to worry much about the performance of drawing them and running their AI. Third, helicopter fly in 3D, so it's a lot easier to make them avoid colliding with stuff. But most of all, they don't have to use traffic lights or worry about traffic congestion or running people over. I was able to avoid the madness of handling traffic jams.

Helicopter flying above the terrain and buildings.

 

Helicopters follow a three segment path where they rise vertically while rotating into position, travel in a straight constant elevation line until they reach the destination, then descend to the helipad below. Once they land they will wait 30-60s before taking off again for a new destination helipad. I should probably make them accelerate and decelerate eventually, but I'm not sure how noticeable that would be. Their max altitude is computed as the max of two values: a fixed distance above the higher elevation helipad (source or destination), and a clearance height above the highest elevation obstacle. I chose to use the terrain and buildings as obstacles to avoid. I'm ignoring trees and smaller objects for now, and just assuming my min vertical clearance value is large enough to avoid colliding with tall trees.

I'm computing max terrain height by walking along the path to the destination and checking each heightmap value along the way. Building max height is computed by ray casting through the buildings and calculating the highest point of each building that the ray intersects. Note that any ray passing completely under a building is guaranteed to hit the terrain, so I don't have to handle this case. This is pretty close, but doesn't account for a helicopter clipping the side of a building. I would have to use a projected cylinder or multiple rays to handle that case. The simplest fix for buildings was to expand building bounding cubes by something a bit larger than the radius of the helicopter. I haven't come up with a good way to handle clipping something like the edge of a cliff in the terrain. I've never seen this happen in practice, so I'm ignoring that situation for now.

One feature I didn't add (yet) is collision avoidance between two helicopters. I added simple bounding sphere-sphere collision detection code, but it seems like waiting until a collision has occurred before reacting is far too late. Maybe it's okay to allow two cars to slightly collide and then move them apart a bit so that they "just touch". It doesn't work that way with helicopters. For one, they can't swerve or slam on the breaks to quickly change direction like cars can. Then there's the danger factor of near collisions. Maybe it's okay to stop your car a few inches before hitting the car in front, and no one will even notice. That's believable in a traffic simulation. However, with helicopters, coming within inches of colliding with some other helicopter mid-air is not cool. You're not going to simply scratch your bumper or dent your license plate if you're a bit off. I can't simply move the two helicopters slightly so that they're not intersecting for that frame and expect it to look believable.

Okay then, how does it work? Collisions must be predicted and avoided ahead of time. In real life it's probably on a time scale of tens of seconds to a few minutes depending on speed. Maybe I can get away with a few seconds of motion prediction in my case. Still, helicopters move pretty quickly compared to cars, and they can cover a lot of distance in a few seconds. They would have to look ahead and predict the paths of potentially colliding helicopters out to a relatively large radius in order to correct their velocity in time. That would result in some form of cylinder-cylinder intersection algorithm, which isn't the easiest to get right.

There's also the question of which helicopter moves first so that they don't actively move into each other's path. Do you ever find yourself trying to avoid walking into someone in the hallway, so you move to the left? Then that person moves to their right, and you're still on a collision course? So you move right instead, and they move left? Yeah, that's what I'm talking about. That game of chicken would be no fun to play in real life helicopters. I have no idea how pilots actually handle that sort of thing.

Anyway, I'm sure I can solve this, but it's going to be somewhat complex. My solution is unlikely to work the first time. I'll have to try something, test it, fix it, and iterate until it works properly and is visually acceptable. Unfortunately, it seems to be nearly impossible to actually get two helicopters to collide. There are only 30 of them in something like 20 square miles of cities, and they have to collide in all three dimensions. Simply crossing each other's paths in the XY plane isn't good enough, they need to be at similar altitudes as well. Okay, maybe that's really a good thing. If helicopters are incredibly unlikely to collide, then maybe it will never actually happen and I can skip implementing collision avoidance completely? It's worth a try. It's one of those tasks where I probably won't add it until I witness a collision months from now.

Here's a screenshot showing two helicopters using two different models that are very close to each other. You can tell by the shadows they project on the road below that they're maybe 50 feet apart and headed somewhat towards each other. However, they're at different enough altitudes that they don't actually collide. The bottom of the helicopter on the right is about 20 feet above the top of the one on the left. This is the closest I've come to witnessing a mid-air collision. Sure, you wouldn't want to have your helicopters fly that close to each other in real life unless it's a stunt show, but that's not close enough to properly test collision avoidance. Also, good luck trying to capture this situation again. I don't remember how long I had to fly around before I found it.

Two helicopters nearly colliding mid-air. You can see their shadows cast on the road below.

The most time consuming step, by far, was making dynamic shadows from moving helicopters efficient. Everything else in 3DWorld's tiled terrain mode is static, which means shadow maps can be generated once and reused across frames. Yes, cars and people are dynamic, but I have no hope of ever having them all cast shadows while getting a reasonable framerate. I haven't even tried.

The big problem here is that this system was never intended to handle shadow updates every frame. The user won't even notice an extra 20ms generating shadows at startup, but adding 20ms to every frame would kill the framerate. There's a lot of stuff to draw into the shadow map: terrain, buildings, trees, parked cars, etc. - I mean, a real lot of objects. On top of that, there are many optimizations that are used for the main draw pass but haven't been implemented or enabled for the shadow pass:

  • Billboard drawing of objects such as trees are disabled because they make terrible looking shadows, so we draw the full model in the shadow pass.
  • Most objects don't have level-of-detail implemented or enabled for the shadow pass.
  • Occlusion culling has been disabled for shadows and wouldn't work well anyway when the sun is overhead because buildings don't tend to occlude too much of the city from that direction.
  • The shadow map is a higher resolution than the screen, which means more work for the rasterizer.

My first attempt at regenerating shadow maps every frame resulted in unplayable frame rates in the 20s or 30s. Then I realized I only had to regenerate shadow maps for regions around the helicopters. This brought the framerate up to around half of what it was without shadow updates, on average. A typical flyover would drop from 110 FPS to 55 FPS with shadows. I later realized that I could also skip updates when the shadow of the helicopter wasn't visible in the player's view frustum. I can get the shadow location by ray casting into the scene using the helicopter's center point and sun direction. The shadow will land on whatever point the ray intersects the terrain or a building. This helped in many situations, but the worst case when the player was looking down at the shadows was still 55 FPS.

I was able to slowly improve this by making various optimizations to specific types of objects that were drawn:

  • Tree low detail (LOD) drawing was broken (incorrectly disabled) for the shadow pass. This was easy to fix.
  • I was drawing every building in the shadow pass. Changing this code to iterate over building tiles and only drawing visible tiles (copy the code from the normal draw pass) helped a lot.
  • There was a performance bug where I was accidentally drawing traffic lights multiple times. The code was supposed to draw the set within each visible tile, but was drawing them all for each visible tile, for both the main and shadow pass.
  • I wasn't bothering to use view frustum culling of scenery objects such as plants and rocks. Enabling that helped a bit.

These changes together reduced the shadow pass frame time by nearly half, giving me ~71 FPS rather than ~55 FPS. This will help in other cases where the light source (sun or moon) moves as well, such as when the player changes the time-of-day or the dynamic day/night cycle is enabled by the user. The visual quality was nearly identical, and I improved non-shadow frame time for the main pass slightly in the process. That's the low hanging fruit, and good enough for now. I added a hotkey to enable and disable dynamic helicopter shadows to allow the user to select between quality and performance.

Here's a YouTube video of me flying around following helicopters as they cross the cities.


You may notice that the blades only rotate on one of the helicopter models. I had to split the model into two parts with the blades rotated differently from the model. This was accomplished by continuously increasing the rotation angle of the propeller while the helicopter was flying. I wanted to use smaller civilian helicopters, but most of the free 3D models I found online were of larger military helicopters. I'm not sure this type can land on typical rooftop helipads. The model I liked the most was in the 3DS file format. It's relatively easy to manually edit a text-based OBJ file model to identify and extract the propeller blades. It's not so easy to do that for a binary 3DS model where everything uses the same material. So for now only one of the two helicopters has rotating blades

I'm pretty happy with the state of helicopters for now. I may get back to them later and work on more shadow optimizations, add more models, improve collision avoidance, or add new types of destinations. I guess we'll have to wait and see.

Friday, January 1, 2021

Procedural Building Interiors: One More Pass?

I'm trying to finish up all the remaining additions I plan to make to procedural building interiors before I move on to other city items. This includes a few new objects and room types.

Interior Objects 

I've added quite a few new object types to building interiors: microwaves, computers, stacks of papers, boxes, horizontal and vertical window blinds, clothes washers, clothes dryers, paint cans, and rooftop solar panels. (Technically, solar panels aren't interior objects, but they're close enough.)

First, I added microwave ovens to some kitchen counters as gray cubes with a microwave texture on the front. This was another one of my daughter's suggestions. A random counter and position are selected, and the microwave is placed at that location if it doesn't intersect any other objects on the counter. I suppose that completes the kitchen, for now. Here's an example screenshot.

This kitchen has a microwave oven in the corner. That completes the basic kitchen setup: table, stove, refrigerator, sink, and microwave.

Up to this point, some desks had computer monitors and keyboards on them, but there was no computer. Fortunately, it's easy to create a simple computer tower by pasting a computer front panel image onto the front of a gray-black cube. Yes, that looks pretty close to the case of the computer I'm using to write 3DWorld and this blog post. I can place these computers under the desk off to one side so that they don't block the chair and can't intersect with anything else placed on top of the desk. Now the office computer desks look more complete.

A computer tower has been placed under desks with monitors, to go with the keyboards.

Some desks have computers, some have books, and others are empty. Empty desks don't look too interesting. Let's add a messy pile of papers on top of some of them. I decided on a mix of mostly white/cream paper with a few yellow pages mixed in. They can be rotated at odd angles and may overlap each other. Objects such as books and bottles can be placed over them. So far I haven't attempted to add any text to these papers; that seems like a major effort that can be done later when I work up the courage to attempt it.

Some desks have a collection of papers scattered on them. The papers are currently colored but blank.

As a final addition to house interiors, I added a chance of placing some boxes on the floor of some room types. Living rooms, dining rooms, bedrooms, and offices can have one or two boxes, while storage rooms can have up to eight boxes. Now I can populate home offices with computers, books, stacks of papers, bottles, and boxes. Here's a representative screenshot of a low-tech (computer-less) home office.

Example home office with a book, papers, bookcase, boxes on the floor, and ... bottle of beer.

Blinds

The next big topic to address was window coverings, specifically for bedroom windows. I originally wanted to add cloth curtains, but I couldn't quite figure out how to add the material with its smooth wavy curves in an efficient way. There are dozens of windows in each house, and I can't add thousands of polygons for every one. So instead I decided to add straight segmented horizontal blinds similar to the ones I have on some of the windows of my house. It was easy to find a free blinds texture with normal map online. Then I had to apply that to a single cube for each blind, which is very cheap to add to every bedroom window.

I used my random number generator to make some rooms have open blinds and others have closed blinds. Then I added a bit of extra randomness per-window so that they were at slightly different heights, which looked more natural. Most blinds are left open to match the previous look of the rooms. Note that open vs. closed blinds don't actually affect the amount of indirect sun/moon/sky light that contributes to the ambient lighting of the room. Here's an example of a room with blinds that are mostly closed.

A bedroom with horizontal blinds on the windows, mostly closed.

Here is a different bedroom with open blinds. You can see that the texture is squished into the top part of the window such that the total number of slats is the same whether the blinds are open or closed. This is to simulate the rotation of the slats as the cords are used to open and close them. I might have to go back and try to find a better solution to the texture aliasing problem when the slats are too close together. I really like the pattern the normal map makes with the lamp light source in this next image.

The lamp makes an interesting pattern of light on the open horizontal blinds of this bedroom.

I can also swap the direction and create vertical blinds for some of the bedrooms. These are a bit different because they start at either side of the window and close in to the center, rather than hanging/extending from the top. Here is how mostly-closed vertical blinds look in the same room as the previous screenshot. The camera is further away from the lamp, near the back wall.

Vertical blinds in a different bedroom, one partially opened and two closed.

That's pretty good for now. I might still add curtains at some point, or maybe add more textures and variety to blinds. I still need to add cloth material to the tops and sides of canopy beds as well.

 

Storage Rooms

Now we move on to office buildings, in particular storage rooms. Since these rooms are only added to the ground floor of larger buildings, there tend to only be a few of them per office building compared to the hundreds of office rooms. Therefore I can add more storage room items than I can get away with for offices. I wanted to make sure I had enough item variety to make these rooms look interesting.

I showed storage room crates, shelves, and bottles in the previous post. Since then I've added cardboard boxes, computers, keyboards, and paint cans. These are all typical items you would find on office building storage room shelves. Computers and keyboards were easy to add because I already had them placed on/under office desks. Cardboard boxes are simple cubes, while paint cans are single cylinders. These shapes are easy to work with, but the process of finding appropriate free textures online was a lot more work. This is especially true for boxes, where I had to manually separate out the top, bottom, and side textures from a texture atlas in an image editor. Here is the end result: a room full of shelves stocked with lots of different items.

This storage room has boxes, two different crate types, and a chair on the floor. It also has boxes, crates, bottles, computers, keyboards, and paint cans packed onto shelves against the walls.

Note that none of the items on shelves are actually stored in memory on the CPU side, and don't have collision detection enabled. The player and "building people" collide with the shelf bounding cubes themselves and can't get onto the shelves to collide with individual items. Also, storage rooms don't have windows, so I don't have to worry about the player viewing their interiors from outside the building. The shelf contents are generated on-the-fly when the player enters the building, converted to raw vertex data, and sent to the GPU. I can add quite a few items because only a few storage rooms are in GPU memory at any given time.

 

Solar Panels

The next addition takes us outside the building and onto the roof. I've added rooftop solar panels to some of the houses. The most complex part of this task was deciding which roof section was the best place to add the panel. The hard requirements are that the panel can't be shadowed by another part of the house and can't intersect any other part of the roof, including the chimney. I excluded smaller roof sections such as garage/shed roofs and porch roofs as well as any triangular roof polygons. This left the larger rectangular areas as valid placements. I ordered them by height so that the upper roof sections (which can't be shadowed by another part of the house) have a higher priority. Then I iterated over them, shrunk them by a fixed amount, and checked for intersections with another part of the house. After numerous iterations, I finally got it working. Here is the result.

Solar panels have been placed on the roofs of some houses in the optimal locations.

I did run into some problems with z-fighting (flickering) when viewing solar panels of distant houses because they were too thin, which placed them too close to the roof. I made them thicker until the problem went away. But now the player can sometimes see the inside surface of the panel when standing below the house and looking up at the roof. I guess the best solution is to draw the sides as well as the top surface quad, making the panels properly 3D. I suppose that looks better overall.

Rooftop solar panels look more 3D when I add their sides.

That's all of the interior objects I had on my list, other than the washer and dryer mentioned in the section below. I think that's pretty good for building interiors. I want to go back and work on cities next, possibly fire hydrants, street signs, etc.


Room Types

I have most of the common house rooms assigned now: bedrooms, bathrooms, kitchens, living rooms, dining rooms, offices/studies, and hallways. I even have a few special room types such as libraries, entryways, and rooms containing only stairs that I call "stairs". And of course there are garages and sheds. The only two common rooms that I'm missing are laundry rooms and storage rooms, so I've added these. All of the currently unassigned rooms in houses are assigned to one of these. The first unassigned ground floor room is made into the laundry room, and any remaining rooms are assigned to storage. Since most houses don't have unassigned rooms at this point, the majority have no dedicated laundry or storage rooms. If I want to change that I have to go back and re-assign some rooms, most likely smaller sized bedrooms.

House storage rooms are filled with boxes and possibly some of the other items found in office building storage rooms. They're usually very small; otherwise a bed, table, or desk would have been placed in them and they would have been made into some other room type by this point.

Laundry rooms have a washer and dryer, assuming both will fit. If only one can fit, then it's the washer. The placer prefers to place both against the same wall if possible. I wasn't able to find any free matching washer and dryer 3D models online, so I had to use a mismatched pair. Here's an example of a laundry room.

A laundry room with (mismatched) clothes washer and dryer.

Next up is helicopters. This post is already pretty long, and helicopters aren't related to building interiors, so I'll save that topic for next time.