Thursday, June 12, 2025

Parking Structures

I'm continuing to work on my series of special procedural building types. Previously I added malls, factories, warehouses, hospitals, and schools. I did go back and add a number of features to those other types. For example, I added locker rooms to schools, hospitals, and industrial buildings. I created coffee machines that dispense coffee and hot chocolate for break rooms. I placed shoes on the floor next to front doors. I added hard hats to factories and warehouses. Computers and mice on desks. Test tubes of blood, valves, and gauges in hospitals. Apples on school desks. Shader-based abstract art pictures in houses. (I might write a separate short blog post on these later.) Those additions aren't the subject of this post though. Maybe I'll show some screenshots of these changes in the next summary/progress post.

This time I'm working on something a bit different that has a new style of building compared to the other types. I've added parking structures, which are above ground variants of my underground parking garages. The biggest difference is that these buildings have open gaps between walls rather than individual windows. This may seem like a minor difference, but making the generation and drawing work in this case was quite difficult. Previous buildings always had the interior window surfaces drawn as opaque when the player looked in from outside. This was due to a technical limitation of how windows were cut out of exterior walls using textures and stencil masks rather than actual geometry. While this did make drawing more complex, it also meant that buildings functioned as occluders for objects behind them. This is not the case for parking structures. The player can see completely through them and out the other side. They're more open air than concrete walls, which means that some of my earlier optimizations are no longer valid.

I did have some trouble with lighting due to the way interior room lights and exterior sun/moon light is handled in two separate draw passes. All building objects are labeled as interior vs. exterior and drawn in exactly one of those passes. The problem with parking structures is that they have walls and pillars along the exterior edges that are visible from both inside and outside the building. I can't use trickery with the depth and stencil masks to draw walls with window cutouts here. What I ended up doing was drawing some of these objects in both interior and exterior passes, with different faces enabled for each pass depending on which way they were oriented. Those vertical pillars along the outside edges are effectively half inside and half outside the building. 

While the exterior is different, the interior is mostly a combination of existing components. I reused most of the existing underground parking garage code to create the above ground variants. This includes all of the logic to insert pillars, walls, ramps, parking spaces, cars, and sprinkler pipes in the ceiling. The only differences were related to anything placed on walls, and the logic to avoid obstacles. I did have to make some changes to object drawing to increase the draw distance of pillars and walls so that they wouldn't disappear when the player walks away from the building like the underground versions of these objects do.

Those exterior pillars I mentioned above are special cases. They're not added to underground parking garages because the outside walls provide support. However, parking structures don't have full height walls, so they need more structural support. I wrote code that attempts to move pillars to the sides in multiple iterative steps if they intersect another object or block the stairs, elevator, or ramp. I also added a type of narrower non-square pillar that is easier to fit into tight spaces. The placement algorithm should ensure there's enough clearance for cars to move around and between fixed structural objects like this. 

I reused the code that attached fire extinguishers to mall pillars to add them to pillars in both underground and above ground parking areas. I also repurposed the code that adds stains to walls and floors so that it places oil stains in some parking spaces.

Below are some screenshots of the new parking structures with indirect lighting enabled.

Parking structure interior with cars, a person, handicap spots, stairs, elevator, red sprinkler pipes, oil stains, and a fire extinguisher in the back center.

Parking structure with walls between rows of parking spaces.

All parking levels are connected by a set of vertically stacked ramps that extend from the basement up to the roof. These ramps run along one side of the building, are wide enough for two cars to fit side-by-side, and have enough clearance at the ends for cars to turn. I added railings on the inside edges and at the end of the upper (roof) level. These are wider versions of the original underground parking garage "ramps to nowhere". The player and building people/zombies can walk up parking ramps, and objects such as balls will roll down them.

Close view of a ramp connecting multiple parking levels.

 

A large and open parking area full of cars, with stains on the ground. The ramp is to the right.

I added the elevator and stairs next to each other on one of the building's sides. Handicap spaces are placed next to these and limited to 5% of total spaces. In my opinion, the U-shaped stairs work better than straight stairs for parking structures. They're more compact and leave more room for parking spaces, though they do look somewhat odd next to elevators due the the large difference in depth. Maybe elevators should be larger? I mixed the stairs up so that they face the same direction as the elevator 50% of the time and are perpendicular and facing away from the elevator the other 50%. Stairs extend from the basement all the way to the roof and are numbered on each floor. Elevators extend from the basement to the top floor. They don't reach the roof because I haven't implemented elevator entrances above building interiors. Technically, city malls have elevator levels above ground, but that's somewhat of a different case to handle.

A closeup of the stairs and elevator. Maybe the stairs need a light like I added to retail buildings?

Each parking structure has a small bathroom in a corner on the ground floor with a toilet and a sink. This uses the same room-inside-a-room logic as hospital patient rooms and industrial buildings. The entire remainder of the above ground building is a single room of type "parking" that covers all floors. Once again, it's much faster to reuse existing code. It's not entirely reused though because I had to add the side walls, as there are no full height exterior walls on the building itself that form the outside walls of the bathroom.

A parking structure bathroom. It's similar to bathrooms found in hospital rooms and smaller office buildings.

That's all for interiors. It's time to discuss the exterior design. Parking structures have a number of exterior doors with a bit of concrete wall to the left and right of them to give them a proper frame. There's also a cutout for the area where cars enter and exit. I added "enter" and "exit" signs, in addition to signs marking the clearance. A driveway extends from the entrance outward, but doesn't yet connect to a road.

Inside the entrance is a pair of ticket machines with gates/bars that can either be raised or lowered. The machines themselves use a texture I found online for the front panel and a yellow and black striped gate arm texture. The arm blocks the player but can easily be walked around. I haven't made these machines interactive yet. 

Now I'll show a few screenshots of parking structure exteriors. Note that the lighting looks different here. This is because 3DWorld has separate lighting environments for building exterior vs. interior light sources. The interior lights from the above screenshots have precomputed indirect volumetric lighting enabled. This only works for the building the player is currently inside (for performance reasons), so there is no indirect lighting visible in this outdoor screenshot. In addition, the custom ambient lighting for parking structures that I used to offset the lack of windows is disabled when the player is outside.

Parking structure entrance/exit viewed from the outside, with enter, exit, and clearance signs visible. Here the ramp is near the entrance.

Parking ticket machines with gates on both the entrance and exit sides. Some gates are open while others are closed.

 

The parking structure roof has a small enclosed area at the top of the stairs as well as the uppermost ramp segment. I haven't yet found a good way to add cars or parking spaces to the upper levels. This is technically the roof rather than an interior part of the building. The normal object placement system doesn't support objects added outside the interior bounds of the building. I have limited support for adding rooftop items, but this doesn't include 3D models. I also can't reuse the code to add cars to parking lots as that only works inside city bounds.

Since the rooftop is otherwise empty, I decided to add something similar to streetlights. This way there will at least be light sources if I do find a way to add cars. This doesn't actually use the same system as city streetlights because it wouldn't be efficient in this case, and again, this isn't inside a city. Instead I used the system I created to add porch lights to houses that collects together all light sources during the building generation step. The performance is acceptable because only around 50 out of 18,000 buildings are parking structures. It seems to work reasonably well, though it doesn't support shadows. I think that's okay because there aren't many shadow casting object on the roof yet anyway, other than the light poles themselves. These lights turn on at night time as the sun sets. They're not all that bright, which I suppose is to be expected for parking areas.

Parking structure viewed from the side and above. There are lights on the roof, but no cars. The big "Parking" sign is also visible.


Night time view of the roof with lights on. It's pretty empty up here.

Update:

Okay, now that I've written about it, I feel like I need to add rooftop cars. My hacky solution is to assign each parking structure a successive "city" index after all of the cities are added. Then I can add some special case logic to treat these roofs like a city with a single parking lot in a single block. It's messy and probably not very efficient, but it works. The existing lighting code happens to be correct as well, including the sun and moon shadows.

Parking structure, now with cars on the roof.

If you compare the images you can see that the lights have changed as well. They now have extra cubes at the bases. They're also now aligned to the rows of parking spaces, which means there are somewhat fewer lights than there used to be. I had to remove lights that were too close to the ramp to avoid blocking the paths of cars. I even modified the rooftop lights so that shadows are enabled and the cars now cast shadows. Of course it does hurt framerate somewhat to do this. At least they're static shadows.

Night time scene with shadow casting rooftop lights.

As usual, I'll probably improve and add to these building types after publishing this blog post. This happens with every new building type. There have been so many small additions that I'll never have the time to write about. Many of these changes are based on user feedback that I get from comments and emails.

Next on the list is factory conveyor belts. These are similar to escalators and moving walkways and should be a fun addition. It shouldn't take me very long to add them!

Sunday, May 11, 2025

Procedural Schools

I've been working on adding schools to 3DWorld's procedural cities on and off for a few months now. I started schools shortly after hospitals, and switched back and forth between working on the two building types. Hospitals got to a semi-finished state first, so I wrote a blog post on them last month. This post will be on the topic of procedural schools. I'm not quite done with schools at this point, but I'm starting to work on other unrelated topics. Maybe reader comments/feedback will give me some ideas on how to finish schools. I definitely got a lot of good feedback on hospitals last month.

As with the hospitals post, I'll describe each new type of room and show at least one screenshot for each of them. Technically, none of the room types is really new, but they're all at least somewhat customized for schools.

School buildings are of the taller and blocky "city" form rather than the strip mall-like one or two floor schools that seem to be more common in areas with more land. I tried my best to fit them into my standard office building templates with a central hallway and optional secondary hallways, with possible vertical stacked parts of progressively smaller footprints. This leads to most of the rooms having similar sizes, which isn't ideal, but I'll try to work with that. I ran into that same limitation with hospitals. Maybe sometime I'll find a better system to create buildings with larger and more complex footprints. I could use that for malls and factories as well.

Classrooms

I actually added classrooms to both schools and hospitals, though they're much more common in schools. In fact most of the rooms in schools are assigned as classrooms. I feel like the classroom discussion belongs in the schools post rather than the hospitals post, so I held off on writing about them until now.

Classrooms have a few requirements. First, there is a minimum room size required to fit at least 3x3 student desks. In order to guarantee most rooms are large enough to be classrooms, I modified the hallway and room generation logic in the office building floor planning step to create fewer larger rooms. One component of this was to increase the threshold or building size needed for adding secondary hallways. Classrooms must also have at least one exterior wall with a window, and no stairs, elevators, or exterior doors.

Most of the space in classrooms is filled with a 2D grid of smaller student desks with chairs, placed in multiple rows and columns as space allows. I copied and customized the code that I used to place rows of shelves in retail rooms. Any desks that are too close to a door or other object are omitted. The placement logic is relatively simple compared to some other room types because I don't need to worry about things like exterior doors, stairs, and elevators. A random assortment of books, papers, pens, and pencils is placed on top of these desks.

A teacher desk is placed against a wall, with preference for the long side of the room and interior walls with no windows. This desk has drawers and the top surface can have papers and an optional cup, which contains coffee 50% of the time. If the wall is windowless, a chalkboard/blackboard is added behind the teacher's desk and covers most of the wall. I'm going to refer to it as a blackboard because I've made them all black rather than dark green. Plus it seems to fit better with "whiteboard" used in offices. I then added an American flag to one side of the blackboard and an analog clock to the other. To finish the room off, I placed a few other objects such as plants, paper and trash on the floor, and room number signs outside the door.

A school classroom with student desks and a teacher's desk and chalkboard in front.

Here's a larger classroom with darker chair colors. The screenshot was taken from inside the doorway to the room, which is why there are no desks or chairs in the foreground.


A second classroom with darker chairs.

Oh! I also changed the titles of most of the books found in schools to match a selection of real school subjects. The list I came up with is: Math, Mathematics, Algebra, Geometry, Trigonometry, Calculus, Science, Biology, Chemistry, Physics, Economics, Computer Science, English, Literature, Language Arts, Social Studies, History, Geography, Government, Sociology, and Visual Arts. Some of these have "I" or "II" suffixes. Unfortunately, I haven't yet found a way to make the subjects match the images placed on the book covers. The textbook subjects found in each classroom are random as well, rather than matching the subject taught in the room.

A student desk with a calculus book ... that has a picture of a museum dinosaur exhibit on it? What does that have to do with calculus?
 

Blackboards come with chalk and erasers that the player can use to draw on them. I was thinking of adding some existing text and drawings on the boards, but I don't know where to get the images from. Drawing text with normal font doesn't look correct; I need something handwritten. Most of the images I saw in Google image search are artistic drawings rather than something you would find in schools. I was only able to find one image of some math that was high resolution, free, not watermarked, and the correct color and aspect ratio. It's clipped at the edges, but otherwise looks okay. This image is added to the blackboards of 25% of classrooms. If I find more useful images I'll add them later. Sadly, erasers held by the player don't work on these images.

Blackboard with some math writing that's somewhat stretched and clipped.

Hallway Lockers

Most larger building types have hallways, but only schools have lockers placed in these hallways. I added rows of lockers to each side of the primary hallway on each floor, wherever there was space. There are gaps in the rows where doors or other objects such as water fountains and fire extinguishers block their placement. Each school building part chooses a random locker color from a selection of light/bright colors. Some lockers have padlocks added to them.

School hallways also have a random chance of papers and trash on the floor. Otherwise, they're similar to office buildings with restrooms, water fountains, fire extinguishers, and trashcans on each floor.

A shorter school hallway with blue lockers and stairs. There is some paper trash visible in the bottom center.

Some of the larger schools have hundreds of lockers lining the hallway. This is probably too many given the number of desks in the classrooms, but it's fine for now. I'm sure some schools have too few lockers as well.

A longer school hallway with red lockers, elevators, and intersecting hallways. There are a few papers on the floor in the back.

The player can open the lockers without padlocks, and of course they contain items. All locker interiors have a larger bottom section and a smaller top section. Both shelves can have stacks of textbooks. Smaller objects such as cell phones, paper balls, bottles, and cans are placed on these books or on the empty shelf. Some lockers have papers attached to the inside of their doors. The larger bottom shelf also has a chance of a hanging colored tee shirt (which is a bit undersized, so I had to add it at an angle).

A school building with light brown lockers. I've opened the ones that aren't locked with a padlock.

Cafeterias

I added a cafeteria to some schools, though it's generally not large enough to fit many students. The minimum size is set so that there are at least three rows of tables. Each row has either a single long table or two shorter tables with an aisle in between. Most building floorplans contain similar sized rooms, which is a limitation. Maybe I should remove walls and merge two or more adjacent rooms into a single larger room? That way it could be used for cafeterias, auditoriums, gyms, etc. Of course I would probably need to increase the ceiling height of these rooms as well. None of this is particularly easy given the way the floor planning code is written and the fact that room assignment is run at a later time when it's too late to change walls or doors.

Cafeterias are similar to mall food courts and use the same table and chair geometry. The main difference is that cafeteria tables tend to be longer than mall tables. Various food, drink, and school items are placed on these tables. This includes cans, bottles, cups, pizza boxes, bananas, plates, silverware, vases, books, and laptops. There's also a clock on the wall. Now that I'm writing this, I think I'll add larger cylindrical trashcans to the corners of the cafeteria.

Cafeterias always have some type of tile floor texture that's easier to clean than carpeting. The rest of the school has randomly either carpeted or tile floor.

A school cafeteria with tables and orange chairs. Yes, that's a can of beer on the left table. You shouldn't be surprised, considering I had beer in hospital rooms as well (see the previous blog post).

Teacher Lounges

Teacher lounges are basically the same as the lounges found in some office buildings. They have a central table with chairs, one or more couches, and optionally a refrigerator, a vending machine, and a wall mounted TV. Here we have the opposite problem to cafeterias: The rooms are too large. I should probably add more items to make use of the extra space. Or maybe place teacher lounges next to cafeterias and move the wall so that half the lounge size is added to the cafeteria? This won't work in general though because there are multiple teacher lounges and only one cafeteria.

Teacher lounge with couch, tables, chairs, bookcase, vending machine, refrigerator, and wall TV.

Libraries

The final room type I've added to schools is libraries. Well, that's not really true. Schools have restrooms, offices, utility rooms, and server rooms as well. What I really meant to say is the final school-specific room type is libraries. Except that some office buildings have libraries as well. Anyway, this is the final type I'm going to discuss in the current post.

Libraries have the expected stacks of books in the form of bookcases against the walls. They also have  normal office furniture such as desks, tables, chairs, and filing cabinets. Sometimes they're small, such as the library in the screenshot below. I'm adding libraries last since they're optional, so they only get assigned to rooms that haven't been set to some other purpose. This means that they don't have much selection based on room size, and some smaller schools have no libraries.

A small school library with bookcases, desks, a computer, and a filing cabinet.

That's as far as I've gotten with schools. There are still some room types that I want to add later, especially if I can get more control over room size and height. It would be nice if I could find a way to add procedural writing on blackboards as well.

The code can be found in my GitHub repo here.

Friday, April 18, 2025

Procedural Hospitals

The next types of procedural buildings on my list after malls, factories, and warehouses are hospitals and schools. I've been working on both of these together, but hospitals were started first and are further along than schools. I'll discuss hospitals in this post and probably get to schools in the next one.

Hospital Exteriors 

My very first addition to hospitals for this round was to add illuminated red crosses to either side of the lit signs on top of city hospital buildings. These use the existing text rendering system with a single "+" character. This is a good start, though it's a minor change that only works in cities and is only really visible at night time.

Night time hospital with emissive green name sign and red crosses to the sides.

Hospital Interiors

The next step was to add ambulances to hospital parking garages. Technically, this isn't the next task I worked on, but it was one of the earlier additions that was completed by the time I started writing this post. Ambulances don't normally fit inside parking garages because they're too tall and may intersect the pipes that run along the ceiling. I had to cheat and shrink them by 20% (compared to ambulances found above ground) so that they fit. It's not too obvious that this shrink was applied. I wonder if I can get away with using this same approach to squeeze a school bus into a school parking garage? Probably not!

Hospital underground parking garage with some slightly smaller than normal ambulances.

With those two minor changes out of the way, it was time to work on hospital interiors. Non-city hospitals are only assigned to larger cube-based buildings where the ground floor part is large enough to add primary and secondary hallways. This allows the existing secondary and ring hallway floorplan templates to be used, with various rooms placed along the hallways. The resulting rooms have relatively consistent sizes that work well for hospital room types.

The only major difference to the hallways themselves is the addition of a reception desk at one end of the primary hallway on each floor, rather than at both ends of the hallway on the ground floor only. These can serve as nurse desks or similar. All of the normal hallway items still apply: water fountains, fire extinguishers, clocks, and US flags.

The major difference between hospitals and office buildings is the assignment of room types. While hospitals can have some office rooms, the majority of rooms are related to hospital services. So far I've added recovery rooms for one or multiple patients, exam rooms, waiting rooms, operating rooms, and classrooms. Each of these contains a different set of placed object types with some amount of overlap.

Patient Rooms

Most rooms along the building exterior that have windows and a single door are reserved for patients. These have one or more hospital beds selected from one of three new 3D models, which are randomly selected per hospital part. The number of beds is a function of room size to best utilize the available space. Rooms that have multiple beds along a single wall have curtains separating the beds. TVs are placed on the walls opposite beds where there's space, and if their line of sight isn't blocked. I also added a variety of other items to hospital rooms including tables with flowers and telephones on them, chairs, couches, potted plants, and the new wheelchair 3D model. Chairs come in several existing varieties: wooden house chairs, plastic office chairs, and occasional rocking chairs. At this time the beds are all empty because I don't have any models of people with a lying down animation.

Here are some example hospital rooms. I've enabled indirect lighting in all screenshots, so they're quite bright inside.

Hospital patient room with three beds separated by curtains, a table, couch, chairs, and wheelchair.
 

Another hospital room with beds, curtains, table with plant, and rocking chair.

Hospital room with a different style of bed, couch, and TVs on the wall.

Very bright hospital room that's long and thin with a third bed type.

Just for fun, I made hospital beds slightly under the max player carry limit. This means that you can pick one up if your inventory is otherwise empty, but you'll be at max carry capacity and extra slow. It makes more sense to move the beds around by pushing and pulling if they get in the way. Their wheels make them movable by the player.

If the room is large enough, it also includes a private bathroom in the corner to one side of the entrance door. Once again I've reused the nested sub-room system from factories and warehouses. The bathroom has a separate light, toilet, sink, and mirror. The placement system ensures both the main room door and the bathroom door are not blocked by anything. Bathrooms are added at the floorplanning step since they require adding walls, which means that patient rooms are selected before the main room assignment pass. This complicates later placement steps as it requires shuffling room types around if stairs are added later or a bed can't be fit in the room.

Hospital patient room private bathroom, added as a nested sub-room in the corner by the door.

Waiting Rooms 

Waiting rooms were the next to be added, since they contain mostly existing objects. The interior walls of the room are lined with rows of chairs and one or two couches. If the room is large enough, an additional one or two rows of chairs are placed against a short wall in the center. I also put a TV on the wall, and either a bookcase with reading books or a vending machine in a corner of the room. Finally, I added either a digital or analog clock on the wall that dynamically updates to show the true time.

Vending machines are a new type of interactive object. These have been placed in office building and hotel lounges and lobbies as well. There are two types of vending machines with different exterior textures, one serving bottled drinks and the other serving snacks such as chips and candy bars. I got the textures, stats, and item lists for both of these from online vending machine ads. I was surprised at the typical cost: $8000 for refrigerated vending machines and $6000 for non-refrigerated ones! Of course the player could steal these for that value, if only they weren't several times over the player carrying capacity.

Vending machines are interactive. They have a fixed number of random items (0-9) that can be purchased for $2 each. Where does the player get $2 from? You have to steal it from somewhere else in the building. Drink vending machines give random drink consumables that have various effects on the player: water, Coke, beer, and wine. Yes, $2 alcohol from vending machines! In hospitals! The first two drinks heal the player and the second two make the player drunk. And if the player doesn't need a heal, that's $2 wasted. Being slightly drunk is a good thing because it increases damage resistance, but being too drunk causes visual artifacts and can eventually kill the player. Snack machines produce a variety of items that heal a small amount of health. I don't know how practical these vending machines are, but they were a lot of fun to add.

I also changed the set of random items the player can loot by breaking into parked cars so that some of them have effects such as healing. Maybe it's too easy to get healed now? Most of my time playing I'm either at full health or dead though, so it may not matter all that much.

Waiting rooms are more commonly placed on ground floors, but can appear at any floor. Rooms that would normally be assigned to patient rooms are re-assigned to waiting rooms if stairs or elevators are added to them later during the "connect" step. However, these rooms may already have nested bathrooms. That works out fine though because these can be repurposed as waiting room bathrooms. Or maybe they're intended for sample collection for lab work? I do need to check for bathroom intersections when placing other room objects.

Here are some waiting rooms that I've come across in the hospital closest to the starting area. 

Hospital waiting room with gray chairs and couch, a TV on the wall, and a bookcase in the corner by the elevator cutout. (The elevator opens to the hallway outside the room.)

Another waiting room with a drink vending machine and stairs going up on the right side. This one has a private bathroom as well.

A very small waiting room with a single couch, at the top of the stairs shown in the previous screenshot. This one has a snack vending machine and an analog clock.

Exam Rooms 

Exam rooms were next. I felt like I already had enough hospital bed 3D models, so I used a random existing bed model rather than adding yet another exam bed model. I placed a doctor's desk with computer, monitor, and phone in the room. Then I added an optional computer monitor on the wall, an optional first aid kit, an optional wheelchair, a filing cabinet, a chair, and a stool. I added either a simple sink or full bathroom vanity with doors/drawers full of items.

Hospital exam room that's probably too large, with bed, desk, sink (behind the bed), wall monitor, first aid kit, and filing cabinet.
 

Ah, that's right, vanities are new as well. I started by adding these to house bathrooms. They're basically the same as kitchen cabinets + sinks, except they're white rather than brown wood and contain a different set of items. They also have mirrors that open, similar to bathroom medicine cabinets. At the moment exam room vanities have the same items found in house bathroom vanities. That will likely change later.

Vanity model used as a hospital exam room sink and cabinet. Those are definitely not cans of beer inside the open door.

All right, I changed them to contain bottles of medicine rather than other types of cans and bottles. But I'm not going to capture a new screenshot for this post.

Hospitals sure contain a lot of medicine bottles. Right now medicine fully heals the player, including the effects of snake and spider venom. Maybe I should add different types of medicines that have different effects? Some of them can be bad for the player, just to make things interesting. Or I can add a time limit to prevent players from using medicine too frequently. Maybe there's a message "can't take more than one dose of medicine in the same minute" or a negative effect on the player.

I feel like I should add some other equipment such as a blood pressure cuff. The problem is that I don't want to fill hospitals with a large number of unique models as that hurts both load time and framerate. A second problem is that these rooms are too large for exam rooms. This particular hospital with secondary hallways has a main floorplan where all the rooms are the same relatively large size, so I can't do much about the wasted space. Ring hallways have a greater variety of room sizes that produce more interesting room layouts.

Operating Rooms 

Operating rooms were added last, mostly because I had a hard time deciding what to add to them. I started with a hospital bed 3D model (again), but eventually replaced it with an operating table. I changed the ceiling lights to be round, larger, and brighter. I added the 3D model of what is apparently called a "trolley" - the metal wheeled cart that holds the operating instruments. I added one or two machines along the walls or in the corner of the room. These are the same machines I previously added to extended basements and factories. They seem to fit with the strange equipment likely to be seen in operating rooms. I also attempted to place a metal chemical/gas tank along the wall, using the same tank object as factories. I placed a clock on one of the walls. Finally, I added another optional wheelchair. It's a nice looking model, so it may as well go into every hospital room type.

Operating room with large and very bright lights, an operating table, some machines, a trolley, and a wheelchair.
 

Another operating room. This one is larger and has a chemical tank along the far wall.
 

There's a good chance that I'll go back to improve operating rooms in the future. I think there's a lot of potential, especially if I can work them into the gameplay somehow. Maybe the player can strap zombies onto operating tables? Maybe the player can use a scalpel as a weapon?

Classrooms 

Finally, there are classrooms. I actually copied these from schools, so I won't show classrooms until the procedural schools post. I suppose these are for training of student doctors, health related classes for the public, and that sort of thing.

Hospitals occasionally contain conference rooms that are assigned during the floorplan stage. These are left over from the office building logic and seem okay to allow. And of course there are standard bathrooms with stalls. Whatever rooms remain that are too small to fit beds, etc. can be made into offices, storage, or utility rooms.


Thursday, March 20, 2025

Procedural Warehouses

My last blog post showed the progress I've made on procedural factories. In this post, I'll show how I've generalized factories to industrial buildings and added warehouses as an industrial building sub-type. I have plans to add other building types such as power plants in the future. These buildings share many elements with factories such as overall floorplan, sub-rooms, wall and ceiling beams, sprinkler pipes, HVAC units, ducts, and fans. They also use many of the same textures such as slotted and rusty metals. Reuse of interior elements allows me to create these variants more quickly with less added code complexity.

Warehouses have some significant differences though, most notably the replacement of machines and tanks with rows of shelves. These are similar to shelves found in existing houses, storage rooms, and basements. One main difference is that they're constructed of plywood and metal frames, rather than wood boards mounted to walls. This gives them a sturdier and more industrial look. A second difference is in the types of objects placed on and around these shelves. There are boxes, crates, and pallets everywhere, both on shelves and on the floor. Ladders have been moved against the exterior walls by the entrance door, and the catwalk has been replaced with a forklift 3D model.

Warehouse viewed from the front near the office and entrance, with people and a forklift nearby. The floor has bottles and stains on it.

The placement system supports stacking of pallets on top of each other, stacking of boxes and crates, and placing boxes and crates on pallets. Most of this was done by extending the existing item stacking and player interaction system to be more general. The player can take all of these objects, but only from the top of the stack. Boxes on top can be opened, and the contained items can be removed. The player and building AI people can walk or step over low objects such as individual pallets, which means the placement system doesn't need to worry about them blocking access to areas of the warehouse.

Warehouses have the same office and bathroom sub-rooms as factories. I placed extra rows of high shelves on the roofs of these rooms to make better use of the open space. These shelves aren't against a supporting structure such as other shelves or an exterior wall, so I added a narrow horizontal I-beam connecting them to the exterior side walls. The player can climb ladders to get behind these shelves.

Warehouse showing a stack of pallets on the floor, the front office with entrance door, and additional shelves stacked on top of the sub-rooms.

Warehouse boxes contain a different selection of items compared to boxes found in houses and office buildings. I reworked the shelf and boxes system to allow a different collection of contained objects depending on building and room type. Warehouse boxes contain some of the common items found in earlier boxes such as bottles of water/coke/beer/wine, toilet paper, and cans of spray paint. But they also have new items, including cases of coke and beer cans, boxes of food, and electronic items such as computers, laptops, and microwaves. I even added boxes containing tiny machines which use the same generation and drawing code as machines found in extended basements and factories.

Items are selected based on a combination of randomness and matching the size and shape of the item to the size and shape of the box. For example, tall and narrow boxes may have computer towers, short boxes can contain laptops, and large wide boxes contain microwaves. The goal of the player should be to find the boxes containing more valuable items such as laptops, while avoiding zombies, snakes, spiders, etc.

A stack of boxes and crates next to shelves placed along an exterior wall. Some boxes have been opened, showing items inside.

Warehouses have several entrances. There's a front entrance that opens into the main office, rather than between the office and bathroom as in factories. This means that I had to modify building door and window logic to allow doors to be placed into sub-rooms that already have custom windows that don't match the upper level windows of the main warehouse area. There's a back garage door that would serve as a loading dock, currently using the house garage door texture. I may continue to work on loading docks if I add warehouses to cities in the future or connect the secondary buildings with roads. For now, it only has a connecting driveway, similar to those added to houses. And there's also one or more optional side entrance doors inserted in gaps between rows of shelves.

Warehouse loading door near the back, using the garage door texture.

Warehouses can be quite large. I originally only assigned industrial buildings to smaller brick structures of three to four floors in height. Now I've modified the config file to create some short and wide concrete block buildings that can serve as factories and warehouses. These look more realistic for this type of building. They also make industrial buildings common and easier to find.

I modified overhead map mode to color code buildings based on category/function. This allows the user to select a building and teleport to that location, which definitely helps to accelerate testing of custom types. It's important to visit both large and small buildings to make sure the interior elements scale properly and look reasonable for the interior areas. I spent quite a while fixing problems like this, in particular cases where basement or parking garage stairs were blocked by or intersecting other objects placed at the ground floor.

Large warehouse viewed by standing on top of the upper shelf over the office room. This vantage point is needed to see the size of the space. The forklift is along the back wall on the left.

What's next? I currently have hospitals and schools on my list. I already started working on hospitals, but I decided to go back and add warehouses first because they were a more natural continuation of my work on factories. I've been working a bit on schools as well. It's still early though, so I have no idea how these will turn out.

Saturday, February 22, 2025

Procedural Factories

Factories were next on my list after malls. When I say "factory" I really mean a more general industrial style of building that also includes chemical plants, storage facilities, and that sort of thing. The factories I've created are collections of machines, tanks, pipes, fans, etc. They technically don't manufacture anything at the moment. Their interiors are very different from office buildings and residential buildings.

The first step was to select an appropriate set of buildings to make into factories. I decided on simple rectangular office-style buildings with a single geometry level and no more than four floors tall. Since I currently have the min height of office buildings set to four floors, this means that factories are always four floors in height. (They don't actually have four floors and ceilings inside.) At least having a fixed height simplifies the object placement logic. The set of buildings meeting the requirements of a factory area somewhat rare, and I was only able to find five of them in the area where the player starts. I even had to add debug markers to locate them since it was hard to tell factories apart from office buildings in the early stages of development. However, there are probably around a hundred factories among the 18K total placed buildings in the default city scene.

Factory interiors are similar to malls in that they have tall ceilings that span the entire height of the building "part" cube. I added smaller sub-rooms for an office and a bathroom inside this larger room, with doors connecting them to the open part of the factory. This makes the factory floor a sort of fat T-shape with smaller rooms in two of the corners, and the front door between those rooms. The sub-rooms are a single floor tall, which means the factory ceiling extends to cover them. This allows me to place additional objects on the roofs of those rooms.

This is the first time I've added proper rooms-within-rooms. Technically bedrooms closest are inside rooms, but they're represented as "room objects" rather than rooms in the code. Plus, building AI people don't enter closets like they enter normal rooms. My underground basement "backrooms" areas also have sub-rooms, though these are handled in yet a different way.

Nested rooms caused many problems with object placement, lighting, occlusion culling, and building AI navigation. One issue is that any spatial query such as point-in-room can potentially return both rooms, so I need to make sure the sub-rooms are added before the main factory so that they're returned by the queries. This was enough to fix lighting and occlusion culling, but AI path finding required quite a bit more work. For example, handling passing through doorways was messy because the door actually connects from the factory itself, so I had to treat it as a sort of portal from one area to another overlapping area. Then I had to handle problems with the T-shaped factory area where the shortest path from one point in the factory to another sometimes crossed through a sub-room. I won't get into the details here.

I don't want to have too much text without a screenshot, so here's a view of the entrance area of a factory. You'll have to read the text below to understand what everything is supposed to be.

Area near the entrance of a factory, between the office and the bathroom.

Now that I had the rooms and doorways worked out, it was time to add the walls and roof. I decided on selecting between one of two concrete block textures for the interior side of exterior walls. I reused the corrugated metal texture I had been using for some of the metal objects in cities for the ceiling. Next, rusty steel I-beams were added on the interior side. Vertical beams are placed between windows along the walls, while an X/Y grid of horizontal beams are placed along the ceiling. Beams are shifted to the sides to avoid blocking exterior doors. Round ceiling lights are hung from alternating beams along one direction.

One of my goals with factory object placement was to use as much existing code and as many existing objects as possible, to speed up the process. I first placed either cylindrical or rectangular metal ducts with vents along the upper walls on each side, using the same code I had used for mall store ducts. I later added an HVAC unit with a fan somewhere along each duct, with pipes extending up into the ceiling and down into the floor.

Next it was time to work on pipes. I modified the code that placed fire sprinklers and their network of pipes in parking garages so that it would work with factories. This allowed me to add red pipes up the wall and across the ceiling, with sprinklers, hanging brackets, and the various required pipe fittings. These pipes, along with some of the other types of factory pipes, extend down into the basement parking garage below. I continued to tweak this code at least a dozen times because almost every other object I added intersected those pipes in some factory I encountered.

I had the idea of adding catwalks and ladders to factories from the very beginning. I started by adding vertical ladders to the sides of the office and bathroom and wrote the code to allow the player to climb up and down them. Initially, I wasn't sure how the ladder controls would work. I wanted to allow the player to intentionally fall/jump off a ladder, so I couldn't use the forward and backward movement keys for up and down movement. Instead, I made the direction of the player's view control movement. If the player looks up they will ascend the ladder, and if they look down they'll descend. Then I placed a catwalk connecting the roofs of the two sub-rooms so that the player could walk between them. The catwalk railings are a bright yellow painted metal, which has good contrast against the shades of gray used for most of the other factory objects.

The floor of the catwalk is a metal grid pattern selected from one of two textures with round vs. square holes. These have alpha masks that allow the player to see between the holes in the grid. Light can pass through these holes as well, leaving interesting shadow patterns on objects below. I liked these textures so much that I created special metal stairs that reused them, and also reused the I-beam texture to create rusty metal railings. These stairs can be found in factory basements, where the degree of rust depends on the water damage variable for each building. Here is an example.

New metal mesh stairs with rusty railing in the factory basement. It's darker down here, so I need to use a flashlight.

I added a second catwalk along the length of the factory near the ceiling, supported by bolts into the ceiling beams above. This is randomly shifted around so that it's not over a doorway or directly under a pipe or row of lights. I placed a vertical ladder along the wall that reaches from the floor to the end of the catwalk at either one or both ends. Then I added an additional ladder to the side of the catwalk somewhere along the factory floor. The player can climb up and down all of these ladders and walk along the catwalk. Here is a screenshot taken from the roof of a sub-room where both catwalks and the top end of a ladder are visible.

Factory interior viewed from the roof of the bathroom. The top of the ladder can be seen in the center of the image and the catwalk to the roof of the office is on the right.

Note that all of these screenshots have indirect lighting enabled. I've made some improvements to indirect lighting, in particular for open areas such as malls and factories. I've also optimized the path tracing/ray intersection code used for building interiors. Now it can calculate indirect lighting for the 100-150 light sources from factory lights and windows in only 6-8 seconds of (background) runtime.

I originally wanted to make factories appear dark and dirty, but all of the windows produce quite a bit of natural light, even when the lights are off. However, it's quite dark inside factories at night.

Factory at night with the lights on. There's still a lot of light, though there are definitely more shadows.

Okay, it's still pretty bright. Maybe I should turn down the intensity of the lights? Then I would lose some of those nice detailed shadows from all the small objects. Things get really dark if I also turn off the ceiling lights. Only the red warning lights are visible.

Dark factory at night with the lights off. Only the glow of the red warning lights is visible.

Here is another view from the upper catwalk. The bright yellow colors of the catwalk railings and the red sprinkler pipes really stand out. The player can get a good view of the machines below from up here. It's also safe from zombies, rats, and snakes. Spiders can climb up to catwalks, though I can't remember ever seeing one on the upper catwalk. Fall damage is significantly more of a risk since it's pretty easy to accidentally fall from a ladder. The railings of catwalks make them relatively safe from falls.

View from the factory catwalk, with machines and pipes below, and sprinkler pipes and beams above.

The factory floor itself is mostly covered by three types of objects. There are machines of various shapes and sizes placed along the exterior walls where there's space, with care taken not to block doorways, the entrance area, or basement stairs. This uses the same code I wrote to add objects to extended basement machine rooms. Each machine is composed of a random collection of axis aligned cubes and cylinders using a random set of metal textures. A few additional objects are thrown in such as a transformer and a water fountain attached to a wall. I did change some of the factory machines to have metal rather than concrete base plates for additional variety.

The center area of the factory consists of a 2D grid of machines and a row of chemical tanks along a random edge. That grid and row may be broken up by other objects such as basement stairs and ladders to create an irregular pattern. Both the tanks and machines are connected by groups of pipes, as well as additional pipes going into the floor. Chemical tanks are capsule shapes with one of several textures applied to make them appear scratched, rusty, or dirty.

Factory chemical tanks, pipes, and red warning lights on the corners of machines.

All machines use the same geometry, which allows me to connect them together with pipes and coils of wire in a correct way. Keep in mind that these machines are stored as only a bounding box and some state flags. The detailed geometry and pipes are only generated at draw time and never actually stored in memory on the CPU side. This means that pipe and coil generation can only use information about the current machine to connect the various parts together. But if we know the neighboring machines are identical and at fixed distances from the current machine, we can determine the placement of every machine part for the neighbors by copying the current machine to the adjacent row and column. This also means that the pipes can be different for each row and column, even though the machines are the same, since the pipes for each machine are drawn independently. Any machine with an object blocking the gap between its neighbor is flagged so that no pipes are added on that side.

So far the floor and ceiling are pretty well covered with objects, but the walls are somewhat bare. I added vertical brown drain pipes to the walls along some of the supporting I-beams. I later added ventilation fan 3D models to alternating windows at the ends of the building. These extend outside the window somewhat. The viewer should imagine the window glass has been replaced with a fine mesh screen. While the set of objects added to each building is the same, I added randomness to their size, position, orientation, count, color, and texture to get sufficient variation to make each factory look unique.

A different, smaller factory viewed from above.

I wanted to add fans to the ceilings, but I only had those residential ceiling fan models from earlier posts. I suppose that's better than nothing. I made 75% of the fans rotate and emit a hum sound if the player is nearby. I then added something for the fans to do: collect the smoke and steam rising from machines. Each machine has a small probability of emitting smoke from it's top center, which will rise and expand until it reaches the ceiling. This reuses the particle system I added for interior building fires.

I liked these dynamic objects that make the scene feel more alive. What else can be added? How about flashing red warning lights? The best place to add these seemed like the corners of the machines on end rows, so that the lights were visible when looking along the edges of the machine grid. These lights look especially nice in the dark, though I didn't make them cast shadows.

As a final touch, I scattered various smaller detail objects around on the floors. There are piles of stacked boxes and crates between machines and in the corners. Some random buckets, paint cans, piles of broken glass, and groups of empty bottles are littered around in the open areas. I also added random balls of paper trash and stains to the floor. Most of this reuses existing functionality that I had added to basements in previous work.

A pile of boxes and crates stacked in the corner of a factory near the fire sprinkler riser.

Factory floor with scattered buckets, bottles, and stains. There are more bottles in the far back.

And don't forget the sub-rooms! The office room has a table and one or two desks, usually with computer monitors. I added either an analog or digital clock to the wall, an optional filing cabinet, and some random crates and boxes. The placement algorithm attempts to leave enough space for the player and AI people to walk around the room and between the two doorways. The bathroom has the usual toilet, sink, and possibly a mirror. The area between those two rooms has a fire extinguisher by the door, a breaker box, and a water fountain on the outside wall. All of the interior walls and floors are the same gray concrete material used for basements. Sub-room ceilings use the office building particle board panels texture.

Factory office sub-room with table, desks, chairs, wall clock, and many crates and boxes.

I put extra effort into making the interior structurally sound. There should be beams supporting all of the interior wall and ceiling areas. Everything is attached to or hung from beams as well, including all of the pipes, the central catwalk, the ducts,  HVAC units, lights, ceiling fans, and window fans. None of the objects should be floating or intersecting any other objects. It shouldn't be possible for the player or building AI people to clip through or get stuck in any objects either. Most of the pipes and smaller items are above head level or have collision enabled.

Finally, it was time to work on the factory exterior. The only major difference is the addition of one or two smoke stacks on the building roof. These use the same brick or stone texture as the exterior. They're not yet connected to anything inside the factory though, but they do emit occasional puffs of smoke. I placed some additional AC units, ducts, and pipes on the roof as well. The ventilation fans sticking out of the windows are also a sign that this is a factory. Oh, and the building name and signs now contain the word "factory" in most cases.

Factory exterior with two smoke stacks on the roof. Fans (well, their motors) can be seen protruding from the windows on the left.

Here is a video showing me exploring a factory using ladders and catwalks. I have people enabled in this video, though they don't do much other than walk around the factory floor area. Note that zombies can chase the player quite well in factories as the path finding does a reasonable job. It helps to ensure enough open space between rows of machines and chemical tanks for people to walk.


What's next? I'm sure I'll continue to add details to factories, just like I continued working on malls for weeks after my big mall post. At some point I'll move onto other building types, possibly hospitals and above ground parking garages. I already have some ideas for them.