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.
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.
When I got back from my winter trip in the beginning of January, I was expecting to start on new building types. But every day of 3DWorld development involves a third new features, a third going back and reworking the previous feature, and a third fixing random bugs unrelated to either feature set. Sigh. This time was no different. I was sort of in a rush to get malls done before Christmas and left some parts unfinished and broken. I spent the first two-ish weeks of January finishing up malls. This post will cover some of the new additions and improvements I made.
Pet Store Animals and Cages
I showed pet stores with fish tanks and rats in tanks in the last post. Since then I've added spiders, snakes, and birds. I've also added cages constructed from rectangular metal bars.
Spider tanks either have one large spider or several smaller ones. They can climb on the glass inside the tank, as well as the bottom of the lid. If the player steals the tank or removes the lid, this will set the spiders free to roam around the pet store and out into the mall. This is not a wise move in gameplay mode as spiders can bite and poison the player. Spiders are the only animal type that use the same update logic when in a container vs. free. The other animals are removed when the player takes their tank or cage.
Snakes are placed alone in tanks with a half cylinder log to hide under. They're not interactive or animated in any way yet. I don't believe the existing snake animation and movement code would produce acceptable results inside a small enclosure like this.
Rats are now sometimes placed in cages, which is the correct way to house them. Both rat tanks and cages have a wood chips texture on the bottom. Rats walk around inside their enclosures and avoid colliding each other using a simplified version of the update logic I have for regular building rats. These are typically smaller than the rats found out in the open on floors, and I had to adjust their leg animations appropriately.
Interior view of a mall pet store with tanks and cages full of spiders, rats, fish, and birds.
Here is a closeup of some rat cages. They're formed from narrow rectangular shapes, which use fewer vertices/triangles than cylindrical bars. It's still more expensive than drawing cages with an alpha tested texture, so they're only drawn when the player is close to the building.
Rat cages in a mall pet store.
Birds are always placed in cages, which vary in color from white to
black to gold. The birds themselves are a random shade of gray that varies from near white to near black. I placed a single stick through the bars of the cage for
them to stand on. This is the same animated pigeon 3D model that you can see
flying around the city, except that it only uses the idle/standing
animation. I should probably add a food bowl at some point.
Bird cages in a mall pet store.
Shoe Stores
Two different people asked me about adding shoe stores. I originally didn't want to add multiple shoe 3D models due to the time required to find and set them up, plus the cost of loading and drawing them. Eventually I caved in and added shoe stores. Yes, the models do add about another second to the load time, and they somewhat reduce framerate. The worst part is that this introduces a bit of lag when the first mall is generated and it needs to load all of the shoe models to calculate their bounds. Is it worth the cost? Probably - I do like the look of these shoe stores.
I placed rows and columns of short walls with shelves in the central area of the store, and more shelves against the side walls. This is similar to the layout of clothing stores and pet stores, so I can reuse that code. I did make the walls a wood texture rather than white plaster for improved color variety. In the fist pass, I added rows of individual shoes in a line along the shelves, all pointing in the same direction. The shoes were intentionally somewhat sparse to avoid dragging down the framerate with too many models.
Initial attempt at a mall shoe store. Note that I've also added cylindrical ducts to some store ceilings. A few of the shoe models seem to have emissive materials for some reason.
That's nice, but shoes do tend to come in pairs. It was quite a bit of work to properly mirror one shoe to get the opposite one. This inverted the normals and triangle winding order, so I had to add special code to reverse back face culling when drawing a mirrored shoe. I also had to annotate each of the eight shoe models with left vs. right shoe so that the opposite could be properly oriented. I continued to place individual shoes on the wall shelves as these are the display items.
I added shoe boxes to some of the lower shelves. This increases variety, and also improves framerate as these boxes have fewer polygons than shoes, and only a single texture. I only wish I had multiple shoe brand textures to use here. The model is animated to open, but I haven't added support for this yet. Here is an updated screenshot of another shoe store with these changes.
Updated shoe store with shoe boxes on lower shelves and pairs of shoes on upper shelves.
Clothing Store Mirrors
It's always fun to add mirror reflections to scenes. I do have a few mirrors in the current malls, specifically in restrooms and in bedrooms sets of furniture stores. Mirrors definitely increase frame time since the scene must be drawn twice. However, if I make them small and narrow, I can cull out most of the scene geometry which isn't visible in the reflection.
I added person height mirrors to the back walls of some clothing stores, at the end of an aisle. I suppose this may reduce the chance of a zombie sneaking up on the player. Maybe at some point later I'll add proper changing rooms. Here is an example mirror.
Clothing store mirror where the player is visible. No, you can't try on clothes (yet).
Furniture and Appliance Store Additions
I got some feedback on furniture and appliance stores, which led me to add more items. Furniture stores now have lamps and potted plants. In addition, I changed some of the placement rules to avoid blocking doors and clipping through walls. Here is an updated view of a furniture store.
Furniture store, now with plants added to living room sets.
Appliance stores now have furnaces and water heaters. I'm not sure these actually belong in a mall appliance store, but it was easy to add these existing items. I also changed the object movement logic to allow the player to push and pull these appliances and plumbing fixtures. This was needed because I found it was occasionally possible to get stuck between objects. It would be fun to add some sort of player object pushing maze/puzzle to these rooms!
Round Support Pillars
I saw a post made by another developer that included a modeled shopping mall. This one had round/cylindrical pillars rather than my square/rectangular pillars, which seemed like a good addition to make. Now 50% of malls have round pillars holding up the walkways. I actually prefer these over the square pillars, so maybe I should add them more than 50% of the time. Here is an example.
Some malls, like this one, now have round/cylindrical support pillars. Shiny!
Food Court Recycling Bins
Someone suggested adding food court recycling bins, so I did this. Now some of the trashcans near food courts are blue recycling bins rather than silver or brown trashcans. This applies to both the round and square variants. I had to place some of them next to stairs and escalators so that I had enough placement spots for both trashcans and recycling bins.
Interactive Store Gates
It's no fun when stores are closed. I changed the store gates to be dynamic and player controlled with up/down buttons next to the gate on the inside of the store. If the gate starts closed, the player can usually still access the store through the back hallway and enter to raise the gate. This is a good way to escape from a pursuing zombie, since they can't use these buttons. And if you're fast enough, the button can be pressed with enough time to get under the door before it closes, locking a zombie inside. This is only a temporary solution though, because zombies can also use the back hallway to escape the store. It just takes them a long time to walk around and get back into the main mall concourse.
Mall Skylights
Malls seem disconnected from the rest of the world because there are no windows. So far I haven't found a way to make windows work correctly and efficiently, in particular due to the alpha blending problems when looking through multiple layers of glass. So all of the malls have been placed underground. I did eventually add skylights in the mall ceilings in cities though. I haven't yet found a way to extend this to non-city buildings, where the ground may be uneven or far above the mall ceiling.
Skylights are cut into both the mall ceiling and the city pavement above, similar to how mall access elevators were added. This can only be done when the area above is open rather than a building or road. Then when the smaller city objects such as benches are placed, areas over skylights are marked as blocked. The player can see through them in both directions. The city, terrain, and sky above are visible from the mall below. I did disable drawing of cars and pedestrians in this case for performance reasons, though they're usually not visible from such a steep angle anyway.
Mall skylight, viewed from inside the mall looking up into the city above.
The player can look into the mall from the city above as well, and even walk over the skylight. It's not perfect. Some of the smaller objects (including people) aren't drawn, and shadows may not be correct. If you look closely you can also see that there are some trees in the city above, but their roots don't extend into the mall below. I attempted to mitigate this problem by moving trees away from skylights, since they're placed later in the control flow.
Standing on the city sidewalk and looking down though the skylight at a mall below.
Building AI Navigation
Finally, I fixed several problems with AI navigation/path finding in malls. In particular, they can now enter and exit malls through the adjacent parking garage door. However, this only works when the mall and parking garage are at the same floor levels. This was previously never the case, but now the placement code will attempt to adjust the depth of the mall so that it can align with the floor of parking garages that are at least two levels tall (since mall levels are 2x normal building levels). AI people can't pass when the parking garage and mall are at different heights because I haven't gotten path finding to work on the odd fan-shaped stairs that lead up to the door on the mall side.
Building AIs can also now use the back hallway stairs and elevators. These were more difficult to handle because they span/connect alternating floors rather than tightly packed adjacent floors that normal stairs and elevators connect to. (Remember, mall floors are spaced two normal floors apart, while back hallways are only one normal floor height tall.) The stairs require walking back and forth four times total within the rectangular enclosed space to move one floor up or down. This logic is hard-coded into the AI path finding system.
The third addition was to allow zombies to use escalators when chasing the player in malls. The escalator code had originally only been made to work with retail escalators that connected the ground floor to an upper glass floor. Now escalators can be arbitrary lengths and the AI path finding code can handle this. The path length estimate code isn't very accurate when stairs and escalators are involved, so they may not take the shortest path. I think this is acceptable because it makes zombies less predictable, and they will often converge on the player along different paths.
Future Work
The next type of building I'm working on is a factory, or possibly something like a warehouse or chemical plant. I'm pretty far along in development already. I've added some basic machines, ladders, catwalks, fire sprinklers, and assorted floor clutter items. I'll have more of an update on this later. I'm sure it will take a long time to complete, though probably less than half the time it took me to implement malls. Every new feature can reuse more of the existing code...