Doors
how to script and implement sliding / rotating wall panels (aka doors)
Functional doors are notoriously one of the most complicated objects to implement for a video game. On this page, we will outline why doors are so tricky and difficult, as well as various time-tested strategies for scripting door behaviors in levels.

The door problem

A rotating door is dynamic level geometry that blocks visibility (sometimes) and blocks movement (sometimes), can be interrupted or locked or destroyed, might be obstructed by inanimate objects or characters... This wide-ranging combination of possible states results in many edge cases that are difficult to handle gracefully.
For an introduction to door dilemmas, see Liz England's blog post "The Door Problem" which touches on the door as a tricky intersection between all departments at a large game studio.
The simplest, most stable bug-free type of video game door is no door. So before you add a door to your level, ask yourself, do you really need a door there?
However, if you must have doors, we discuss two categories of door problems: movement and state.

How to handle door movement

First, decide on the type of door movement to implement.
Sliding doors are much simpler than rotating doors. They can recede into a wall / floor / ceiling, and cannot be easily blocked from opening. However, a sliding door does imply a powerful or industrialized society that can manufacture and operate sliding doors, e.g. a huge portcullis, canal lock, sensor-based glass supermarket door, or futuristic sci-fi Star Trek door might be inappropriate for your level's fiction.
Rotating doors sweep over a large area and easily trap objects, and can be easily blocked from opening or closing by standing in the way. This makes their physics more complicated than sliding doors. Yet they are much more mundane and commonplace in the real world than sliding doors, and imply non-futuristic worldbuilding.
For most door physics problems, err on the side of player convenience, even if it's unrealistic or unfair. That's our basic guiding tenet behind these general practices for handling door movement and collision:
  • For convenience, rotating doors should be double-hinged and open in both directions, outwards / away from the character opening the door. (via The Last of Us 2)
  • If NPCs can use the door, their AI should "pinch" through the doorway and avoid blocking others. If NPCs have pathfinding AI, dynamically generate or manually place AI hint nodes to force NPCs to stay away from the door unless they are using it. (via Half-Life 2)
  • If the level is about exploring, let opened doors remain open so that players can track where they have been. But if the level is about high tension or combat, slowly close doors automatically behind the player to simplify the encounter space. (via The Last of Us 2)
  • When using physics engines, try to physically simulate the door hardware, i.e. apply torque or velocity on the rigidbody / hinge, so that it can interact with other physics objects "for free". (via Gone Home)
  • Doors must clear any blocking obstacles in order to close.
    • Ouake-style doors inflict damage forces on blocking objects, sometimes killing players accidentally. This mechanic transforms doors into mild hazards, which fits a chunky arcade action game like Quake, but it's obviously not appropriate for other genres.
    • If the final state of the door does not matter, then let the door end its movement ajar, and disable the door closing force once it collides with another objects (via Gone Home).
    • However, if the door must be forced shut no matter what, then apply a distance-attenuated force to push away nearby objects, with an upper bound on the force. (via Bioshock 2)
"The player could also attempt to walk into an opening door, and being of infinite strength, essentially tear it off the hinge." Developer screenshot in Gone Home, from post "Code Judo" by Johnnemann Nordhagen

How to handle door state

Levels often have a variety of doors, so the core door script must support different behaviors. If there is no pre-existing door entity in your toolset, you may have to engineer your own.
The most basic type of door has two states: open or closed.
But an animated door can also be moving -- opening or closing -- and some doors could be partially-open (ajar). You might need OpenStart, Opening, OpenFinished events, as well as CloseStart, Closing, and CloseFinished events. These different events provide useful places to insert sound hooks, animation, or physics impulses.
Some common parameters and settings to expose for a door object:
  • moveDistance / rotateDistance, in engine units (sliding door) or degrees (rotating door)
    • some projects or use cases may need a configurable axis of movement (e.g. a drawbridge does not rotate around its "up" axis)
    • rotating doors need a hinge position, either configured as a physics hinge object, a mesh origin, or configured as a local positional offset Vector3
  • moveSpeed / rotateSpeed, in engine units per second (sliding) or degrees / second (rotating)
  • delayBeforeClose, in seconds. A value of -1 could mean "stay open, never close automatically."
  • startsOpen, true or false. If true, the door will automatically open itself at the start of the game / default to its open state. A more complicated door might implement this as an initialAjarAngle value instead. In the level editor, door objects should always be placed in their closed position.
  • openOnTouch, true or false. If true, the player can touch or enter an invisible trigger to open the door; if false, the player must manually activate the door or use a button.
  • isLocked, true or false. If true, the player cannot open the door by default, and must unlock the door by finding a key or disabling the lock somehow.
Additionally, you may want to expose different ways of opening or closing the door for level designers. Implement basic Open(), Close(), and Toggle() functions, as well as a ForceOpen() or ForceClose() variant that might apply additional physics hacks or teleportation to ensure the door changes state regardless of obstacles.

Locked doors

The simplest locked door state is true / false. However, this binary doesn't always reflect how we use locked doors in level design. Locked doors can become surprisingly complicated:
  • What if some locked doors can always be closed, while other locked doors cannot be open / closed no matter what? These are two different types of locked door.
  • What if some locked doors are fake doors that lead nowhere and serve only as set dressing to fill wall space and imply diegetic circulation? This is another different type of locked door.
  • What if some doors can be lockpicked, but certain quest-related critical path locks require the specific key? (e.g. Skyrim) These are yet another two different types of locked door.
  • What if a global quest event locks all the doors in the entire game, but then after the quest, unlocks all those locked doors -- how can we distinguish between doors that were previously locked and should remain locked, and previously open doors that should now be unlocked? (In the case of The Witcher 3, a level designer had to manually re-configure every door in the entire game, see "How A Designer Accidentally Opened Every Door In The Witcher 3")
Last modified 2mo ago