Sunday, June 6, 2021

Procedural Buildings: Making Everything Interactive

My new goal for procedural buildings gameplay mode is to make nearly every object interactive. This includes all of the various smaller objects, appliances, room fixtures, etc. Basically anything that can be picked up or has moving parts. When I say "interactive," I mean the player can either pick them up and somehow use them, or use the interact key on them in-place for some effect (animation, sound, state change, etc.) Any object a person would expect to be able to pick up or change in a real building should be interactive here. At this point I've handled the majority of smaller objects, as explained in the sections below.

New Interactive Objects

I've added lots more object types that the player can be picked up and use. In addition, I made the mouse wheel switch between usable items so that the player can freely select among the inventory items. This allows for more flexibility and improved player "artwork." For example, if you have multiple colors of spray paint or whiteboard markers, it's much easier to change colors to create more complex designs.

The player can now either pull the toilet paper down from the hanging roll, or remove rolls of toilet paper from the holder. These removed rolls can then be carried around and dropped one square at a time on the floor or on top of other objects. I originally intended to stretch the paper out in a continuous band so that it could be wrapped around objects. Unfortunately, I was never able to make that look visually correct, or behave properly when the player or AI walked through it. Instead, I had to go with simpler individual squares. A single roll has 200 squares, and the roll will gradually decrease in radius until they're all used up and the inner tube is all that remains.

Check out my toilet paper artwork, made with individual TP squares dropped on the floor.

Kitchen cabinet doors can be opened, similar to desk/dresser/nightstand drawers. They don't yet contain items. I haven't modeled or drawn the cabinet interiors, so for now they simply show as black quads drawn over the opening. I also tried adding transparent holes, but those only show the interior of the wall behind the cabinets. It's not great, but it's better than drawing the cabinet faces and making the doors look fake. I'll have to get back to this and improve it later, then hide additional items in cabinets.

All of the kitchen cabinets have been opened. There's no interior yet, just a black hole sucking up all the light.

Kitchen sinks, bathroom sinks, and bathtubs can now be turned on and off. Sinks have simple animated water drawn when turned on, using a single partially transparent textured cylinder. The nearest sink generates a looping sound of running water that fades with volume based on the distance to the player.

Both bathroom sinks have been turned on, showing running water. It even shows in the mirror reflection.

Players can now enter and hide from zombies in bathroom stalls and showers, as long as the doors are closed. This will display a "[Hiding]" message near the bottom of the screen so that the player is aware that they're safe. I'm not sure how much sense it makes for someone to hide from a zombie in an all glass shower, but it was fun to add. It's not like my zombie gameplay makes much sense anyway!

I'm hiding in this shower stall with the door closed, and the zombies in this room are too dumb to notice me.

The player can interact with various appliances. Microwaves beep, TV channels can be changed, and computer monitors can be turned on and off. I plan to eventually make the rest of the appliances interactive in some way. Maybe I can figure out how to open the doors on some of the 3D models.

Players can open and close the blinds on house bedroom windows. This works with both the vertical and horizontal styles of blinds. I haven't implemented the logic to change the ambient lighting in the room because it's unclear how to do that efficiently without re-processing the lighting for the entire building. If I ever find a better way of doing indirect lighting, I'll make this work somehow.

Basketballs and soccer balls can now be throw at other objects to interact with them as well. For example, you can throw a ball at an elevator button or light switch to press it. (Since balls aren't normally found in office buildings, I allowed the player to carry items between buildings in some cases in order to test this.) Balls can be thrown at TVs and computer monitors to turn them on and off. I plan to model damage to these types of items and maybe also windows by adding crack decals in the future. Another example is that balls can be thrown at pictures hanging on walls, which will tilt them.

Boxes

I explained how items can be nested inside other items in my previous blog post. What better way to increase the level of object nesting than allowing players to open boxes, revealing another level of hidden items inside. Unlike drawers that can only contain a single object, boxes can contain as many objects as will fit. I've written a placement algorithm that will attempt to stack them up or place a X by Y array of objects inside. These objects include books, toilet paper, paint cans, spray paint, bottles of water/coke/beer/wine, soccer balls, and basketballs. The contained items are less interactive and can't be used as consumables (power-ups) to make the game a bit more fair for the zombies.

When open, the 3D model of a box changes to expose the four open flaps. I check for collision of each flap with the room walls to avoid incorrect geometry intersections. These colliding flaps are bent further upward to avoid the wall. This can be seen in the bottom box in the stack to the right of the image below. Note that box flaps are not yet checked for collisions with other adjacent or stacked boxes.

All of the boxes in this storage room have been opened, revealing wine, spray paint, books, etc.

This change significantly increases the total number of items found in buildings, especially those with many boxes. However, these nested items aren't generated or drawn until the player opens the box. So I don't think it's going to affect performance too much unless the player spends hours opening thousands of boxes across many buildings in a local area. Note that once a box is opened, the state will be saved even if the player moves far away from the building and comes back.

Closets

I had previously only allowed the player to open and enter smaller closets with standard hinged doors. Now I've extended this to all closet shapes and sizes. Medium sized closets have doors that fold to each side, and larger/wider closets have doors that slide to each side. Since these closets have more interior space, they can contain a wider variety of items. This includes the usual boxes, and also lamps, computers, keyboards, and paint cans.

Here's an example of a closet with folding doors, followed by a closet with sliding doors, followed by a different closet with folding doors. I turned the closet lights on to make the items on the floor easier to see.

A medium sized closet with folding doors containing a lamp, box with a soccer ball, and box of colored spray paint cans.

A large closet with sliding doors containing a computer, box of toilet paper, basketball, etc.


A closet with folding doors containing a lamp, can of paint, computer, and some boxes.

Each closet has its own hanger rod and ceiling light that can be turned on and off by the player, or stolen for money. The player can close the closet doors and hide from zombies. When the doors are closed and the light is off, the interior of the closet is very dark. At some point in the future I may add clothes hanging in the closets.

Light Switches

The player has been able to turn room lights on and off with the 'S' key for a while now. However, I thought it would be better to add light switches to each room. These are generally placed next to a door in a way that the open door doesn't block them, and they're not obstructed by furniture and other objects. Rooms with exterior doors have multiple light switches, one at an interior door and another at an exterior door.

Every room now has at least one light switch on a wall next to a door.

I used white wall plates with rocker switches that change position when the player uses the interact key. This is the style of light switches used in my actual house. Each switch will toggle all lights in a room, unless the player has stolen the lights from the ceiling.

Book Stacking

Up to this point, soccer balls and basketballs were the only type of item the player could pick up and throw/drop. That's no fun, we need more drop-able items. I decided to allow the player to place books on the floor or any other flat horizontal surface, including stacking them on top of boxes and other books. The stack can be made as tall as the player can reach, or up to the ceiling when collision is disabled (flying mode). Books can be picked up again from the stack if they have nothing resting on top of them - in other words, only from the top of the stack. Stacking books on furniture such as nightstands and tables prevents the player from taking those items unless the books are removed.

Books stacked by the player on a table. Each stack has proper collision detection within the stack.

Books can now be removed from bookcases. Between individually placed books and those found in bookcases, drawers, and boxes, there are plenty to work with in most buildings. Some of the larger buildings contain thousands of books. There's no hard limit on the number of books that can be brought to one place.

I haven't added any true gameplay purpose for books yet. Maybe I'll allow players to throw them at zombies. Maybe I'll enable collision detection so that they can be stacked up to block the path through a doorway. Or maybe I'll hide something of value in some of them. I'll have to think about that later.