Saturday, December 20, 2025

Restaurants and Kitchens

I'm continuing my work on 3DWorld's interiors for special building types. This post will cover some additions I've made to procedural buildings: kitchen pantries, walk-in freezers, commercial kitchens, and mall food court restaurants. Each of these features required implementing new object types and placement algorithms. The last three are also related by containment, since restaurants contain commercial kitchens which contain walk-in freezers. I'll discuss these four topics below in the (inside-out) order in which I added them.

Kitchen Pantries

Up to this point, only retail stores contained food items. I put a lot of effort into making some of these objects, so I wanted to add them to houses as well. Many houses have a pantry in the kitchen, which is a small room for storing food related items. It's actually quite similar to a single door bedroom closet, so I decided to reuse that code. Pantries are placed in one of the corners of the room that doesn't block a window. The only real differences are that these "closets" are in kitchens rather than bedrooms, contain shelves instead of hanger rods, and have food items in place of clothing. The walls, door, and ceiling light are identical to closets.

I decided to add three rows of shelves that wrap around three sides of the interior. The side with the door is of course excluded. A random type of object is selected for each side of every shelf, and in some cases are added to the floor under the bottom shelf. This is the same set of food items placed in retail stores: boxes of crackers and cereal, bottles of water, Coke, beer, or wine, and cans of Coke or beer. I thought of adding pizza boxes, but they generally don't fit on these narrow shelves. Here's an example early version of the kitchen pantry.

Kitchen pantry filled with food boxes and drinks.

I later added non-food items that are still food related such as stacks of plates and rolls of paper towels. I'll continue to add more items when I think of them, or when I add new food related items to other room types in the future. Keep in mind that the player can take and use all of these objects.

Kitchen pantry in another house, with the addition of paper towel rolls.
I added one new type of object for pantries: the spice jar. This is a small semi-transparent glass container with a random amount of colored "spice". These are usually placed in a row on a shelf with various types (colors) of spices randomly selected. Sometimes the placement is uneven with gaps. It's a simple addition, but everything helps to improve realism and variety.

Kitchen pantry with a row of jars of spices. And a rat on the floor!

Walk-In Freezers

Next, I added have walk-in freezers. And guess what? I reused the closet code yet again! In fact, walk-in freezers were copied from pantries since the have the same shelf system. The major difference is in the materials used. In place of plaster walls there's shiny steel for both the interior and exterior. The hardwood floor and wooden door are replaced with metal flooring and a metal door. Even the shelves are metal, in the form of a horizontal grid of thin bars.

Freezers are placed in a corner of the kitchen. These are always one standard floor spacing tall and don't extend to the tall ceiling of mall stores, which means that the top surface may need to be drawn. I added extra clearance around the door to allow it to open (with a different sound). The door is still recessed and thin because it uses the same geometry and rotation logic as interior building doors.

Walk-in freezer in a commercial kitchen, exterior view. Shiny! In fact  most of the kitchen objects are shiny.

Now I'll show the freezer interior. I placed a freezer fan in the top back of the interior using the same code as house AC units. Shelves are metal racks with some vertical supports at the inside corners and objects placed on or below them. I didn't really have any good frozen object types other than stacks of pizza boxes, so I added closed cardboard boxes that the player can imagine has some type of frozen food in them. They can't be opened because I don't have anything good to draw inside the opened box. I may place additional items in freezers later when I think of them. Maybe frozen fish?

Interior view of a walk-in freezer with shelves full of boxes, a few stacks of frozen pizzas, and an AC unit in the top back.

Commercial Kitchens

Pantries and freezers were relatively easy to add. Now that I had freezers, it was time to start on commercial kitchens. These rooms are placed in buildings that can have cafeterias or other eating areas such as schools, prisons, hospitals, and malls. One easy first step was adding a tile floor over the concrete, carpeting, or whatever base floor material the building was using. The remaining steps proved far more difficult, mostly due to the large number of new object types I needed. At first I attempted to create these various kitchen appliances with procedural geometry. I didn't get very far though before I realized it would take countless hours to write the code for all of these. So, with a heavy heart, I deleted the initial code and went looking for 3D models. At least the freezer is procedurally generated.

I found 12 different commercial kitchen object models on Sketchfab which included refrigerators, ovens, microwaves, deep fryers, stoves, grills, and sinks. Most of these were low poly models that should allow me to add quite a few objects without running into framerate problems. I tried to find models that had plain white textures so that I could more easily change the materials. Combined with the existing refrigerator and walk-in freezer objects, that meant I had a total of 14 item types to place. The goal was to add a system that selected and placed random models like I had done with prison gyms.

I already have some nice functions to place 3D models along walls that checks for blocking windows, doors, stairs, other objects, player/AI paths, etc. It takes a height value and automatically calculates the object width and depth based on the relative model sizes in each dimension. My first attempt to use this approach created a random set of objects scattered around the perimeter of the room with gaps of empty space everywhere. That's a reasonable start on the programming side, but it's an absolute mess visually and looks like a very inefficient kitchen layout.

This needs a number of fixes. First, I need to solve the problem of everything placed along the perimeter that leaves empty space in the center of the room. If the kitchen is large enough, a procedural metal table is added in the center. I can then place a variety of smaller items on the table such as the small deep fryer model, a microwave, a toaster, and cooking items that include pans, plates, cups, and trays. I even found a simple 3D model of a milk carton to add. The center of the kitchen is no longer empty space.

The second part of this fix was placing some random rolling carts in areas of empty space. I reused the "trolley" model I had placed in hospital operating rooms, since it seemed like something that could be found in the kitchen. Then I placed stacked plates on these, and configured them so that the player could push and pull them around. (This is important because these carts can sometimes block the path to the door.) One problem down, several to go.

The next issue is the random gaps between objects. Normally a commercial kitchen is packed with adjacent appliances to fit as much as possible into the limited space. Rather than randomly placing individual objects, I changed it to place a single seed object and then iteratively add new random models to each side until there's no available space left. This produces a dense group of adjacent objects along one wall. It's not always the entire wall, as objects such as doors break up the groups.

It's still a mess of object types though. To make matters worse, some of them have very different aspect ratios that don't fit well together. The solution to this is to group the objects by function, which conveniently also somewhat groups them by size and shape. The three categories I came up with are:

  • Objects needing a vent/hood: grills, fryers, stoves
  • Other cooking related objects: ovens and microwaves
  • Non-cooking objects: fridges, freezers, sinks, and dishwashers

Each of these categories has 4-5 different items/models. The entire contiguous group of objects is assigned the same category. Categories are randomly selected, with a higher weight given to the one with the fewest placed objects so far. The placement system also attempts to place at least one of each unique object when possible. This approach mostly balances out the model distributions and maximizes variety. This did a reasonable job of object placement and created a kitchen that looked much more organized.

The only remaining problem was that the models used different colors, materials, and styles. They didn't all fit well together. So I did the only reasonable thing I could come up with: make everything uniformly shiny. I Set almost every material to reflective metal, which removed almost all of the color and texture. The appliances also now match the metal freezer and center table as well. Even the trolleys are shiny metal. Everything is better when it's shiny, right? I need to take advantage of the cube map reflections I added a few months ago. It's actually less obvious that reflections are incorrect when the room is full of many small objects with surfaces at different angles.

There's still one thing missing: ventilation. Kitchens need good airflow to remove all of the smoke, fumes, and steam from cooking. I began by adding rectangular ducts with vents along the ceilings using the same code I had added for malls. That's a good start for general ventilation, but I needed something more industrial for the fryers and grills. After changing my mind a few times, I eventually decided on rectangular metal hoods with internal fans hanging on the ceiling above the first category of items (grills, fryers, and stoves) and spanning the bounds of the entire row of models. That's another bonus of combining rows by type.

Since hoods have to scale to the size and shape of the objects, I create them procedurally rather than using 3D models. These objects have sloped edges so that the front is higher than the back. I added a repeating fan texture to the interior top surface (the same as an AC unit) and a metal grid texture (street grate) to the back.

With everything combined, here is what we get: 

Commercial kitchen inside the windowless room of a school. Shiny!

Very large commercial kitchen inside a prison, with a central table and appliances lining the walls. An open freezer is in the back.

Stoves and some grills have pans on them. To finish things off, I placed some stains on the floor using common food colors like white, black, dark red, and dark green. I liked the look of those stains, so I added similar stains to some of the trays and plates as well.

Mall restaurant kitchen showing some new features such as fish on plates, objects on trays, and stains on trays.

I'm sure I could add more objects such as pots, pans, hanging utensils, etc. to fill in the remaining empty spaces. I don't want to load or draw too many 3D models just for kitchens though. It may be okay if I can find models that can be added to other room types in the future. We'll see.

Mall restaurant kitchens have counters that run their length and separate them from the public areas. I placed more food related items on these counters.

Mall kitchen with a bowl of apples on a counter.

Mall Food Stores/Restaurants

My final food related addition was mall restaurants. These aren't the fancy sit down restaurants with small tables though. No, they're the type of fast food places typically found at food courts. I felt like this simplified layout was an easier place to start. I actually worked on restaurants and commercial kitchens at the same time as this required several iterations to get right. There are also many similarities between the two, in particular the metal surfaces and the various placed food items. And of course commercial kitchens account for about half of the interior space of the restaurant.

There are two different styles of restaurants. The first type has a simple counter and no public interior space. This is your typical fast food counter full of cash registers where customers order their food and then sit down at the central mall food court tables to eat. These are divided into a smaller space where the cashiers and packagers work and a larger back kitchen area. Here are two examples of this type of restaurant, viewed from both inside and outside.

Mall restaurant shown from inside looking out into the mall concourse. The reverse side of the image above. The cash register model is new. Note that some of the store sign backgrounds are colored now.

Mall restaurant walk-up counter with cash registers. Orders to go only. Note that the name sign is directly above the order counter. I really should be using multiple fonts for these signs.

The second style has a public area with entrance doors and large store front windows. This is the same geometry as non-food stores found in malls. In fact I had to add custom code to remove the doors and windows for the counter-only restaurants described above. Here the counter with the register is further inside and separates the public area from the kitchen. I placed a food and drink vending machine in the public section if they fit.

There are two sub-types of this style of restaurant, chosen depending on the size of the public area. If the space is deep enough, rows of tables are added and this becomes a sit down restaurant. Otherwise, the public space is left mostly empty except for the vending machines. Customers buy their food and then go back to the central food court area to eat it. I may decide to add more small items here later. Below are screenshots of both the empty space and tables cases. 

Mall restaurant with an indoor area for ordering and vending machines, but no seating.

Mall restaurant with indoor seating. Vending machines are off-screen to the sides.

I'll finish this post by showing some of the new detail items that I've added to restaurants. First, I added a bowl type to complement the plate type. The only real difference is the use of a spherical section rather than a conical section when drawing. Bowls can be empty or contain apples or soup. Soup is drawn as a simple circle at a random height, using the same set of food colors as floor stains. I reused the liquid drawing code from cups of coffee and buckets.

Bowls of apples can be seen in the screenshot below and also an earlier commercial kitchen screenshot. I originally wanted to use a sphere packing algorithm to place the apples as densely as possible. Unfortunately, packing spheres into a spherical section is quite a complex problem, and I wasn't able to find a simple mathematical way to do that. It's really not worth spending days working on the solution to such a minor feature. So instead, I placed one apple on the bottom and three more in a second ring/level. The player can take apples and then take the bowl itself when empty.

If bowls can be nonempty, then some plates should be nonempty as well. The only existing object I could find that worked well for a plate was a fish. I can conveniently reuse the same fish model I have for house aquariums, I just have to flip it on its side. I can even take advantage of the stacking/containment logic and place these new nonempty bowls and plates on trays. Now you can find a fish on a bowl on a tray on a table, and the game logic requires the player to pick up these objects in the correct stacking order to avoid having anything become floating in the air. The stack of objects will also move with the table if pushed by the player.

As an added bonus, I can reuse some of these food related objects in house kitchens and cafeterias. 

Closer view of bowl of apples and fish on plate on tray.

Abandoned bowl of soup on a tray on a cafeteria table.

Wow, that was a ton of work! I'm surprised I was able to get all of this done before Christmas. I feel like I'm not 100% done yet. I'll probably spend a few weeks debugging, tweaking, and optimizing kitchens. Maybe I'll go back and add some smaller objects to fill the empty space.


No comments:

Post a Comment