Programming Blog 10 – Dastardly Doors

Hello, Bean and Steph here!

Doors. You may have heard of them. You may have even walked through one yourself. Well, it turns out this seemingly simple piece of modern technology becomes fraught with problems and design issues when it comes to including them in a video game. A recent article entitled “The Door Problem” [Gamasutra Article] highlighted this as a common design challenge that many games need to solve. For example, how will the doors in your game work? Can doors be locked? If so, how can they be unlocked? How big are they? Can every door be opened? In this blog we are going to explore some of the door challenges we had, and what solutions we came up with.

Why doors?

In Monstrum, the player will be exploring a vast ship in order to find a means of escape. It would be weird if the ship didn’t have doors, so unfortunately we couldn’t just skip the whole door problem. Blast! So we added some simple doors and following that, everything was sunshine and roses and we retired early to the countryside and drank a cold beer. Well, that last part might be a lie.

Door == Doom

While at first glance things seemed OK, we later noticed that when it came to running away from the big bad monster using doors would always end in death. Why? We couldn’t get through the door fast enough. In a rush, we often misjudged the movements required to back away from the opening door and the moment to run forward, causing us to be on the wrong side of the door. By the time we corrected our mistake, the monster had already caught us.

We figured that if we pushed the player backwards automatically whilst the door opened, it would streamline the actions required to move through it. But what direction is backwards? Well, we tried a few different likely candidates: along the player’s normal, along the door’s normal and along the door frame’s normal.

 

The player’s normal and door’s normal were quickly rejected, since they end up with the player on the wrong side of the door, sometimes trapping the player in geometry at the side of the door.

However, the frame’s normal turned out to be the most consistent and felt the most ‘right’, so we stuck with that. These weren’t our only options, but we were happy with the results.

Now all the player had to do was hold forward, and the game would let them run through the door as soon as it was possible. Hooray! With the help of a couple of triggers, suddenly figuring out how to meander around the door was a thing of the past. But then we had another problem.

Let me go!

The problem with our simple method is that it would often grab the player and move them when it wasn’t appropriate, such as when the door was opened from the other side.

So we needed a better method to detect when the player would want help from our push-back system. Firstly, we assumed that the player would only want to be pushed if they were in the way of the door. This could be detected by figuring out which side of the door they are.

For this we took the angle between the door’s normal and the direction from the door to the player. If the angle was < 90°, push the player back. Turned out this worked pretty well! If the angle was > 90° we knew the player was on the other side of the door, which was useful for a similar push-back system for when the player closed the door. We also only applied the pushback effect if the player was close enough to the door (using a raycast to get the distance). When closing the door, we used triggers instead of a raycast, since we wanted more precise control at the edge of the door.

A wizard is never late…

This system got us most of the way to what we wanted. The player would be pushed back until the door was open, and then allowed to go forwards. Great! But we wanted better. Our system was pessimistic, and by that we mean the door would wait until it was fully open before the player could run through. But we knew there was definitely an earlier point they could run through the door without problems – we just had to figure out where that point was. In the end we settled for a raycast from the player to the middle of the door frame; as soon as the door was out of the way the ray wouldn’t hit the door and marked the path as clear. This particularly improved slower-opening doors.

A Conflict of Interest

Another chain of problems we had involved whether or not to lock the player’s normal movement when being pushed back. At the start it was not locked; a result of this was that if the player decided to run in to the door whilst being pushed back, it caused an erratic jerky motion as the two movements conflicted. We tried increasing the push-back speed, which helped somewhat, but then the opposite happened: when the player stopped moving, the push-back amount caused a clear jump/small teleport in movement away from the door.

Next, we tried locking the player’s standard movement. The jerkyness was effectively gone! However, this felt far too restrictive, as it prevented the player from moving sidewards and backwards (manually). The solution we devised for this was only locking the player’s movement when they were moving towards the door. We worked out when this was the case by finding the angle between the player’s movement direction to the door frame’s normal. This seemed to work!

A final word

It is worth noting that the doors in Monstrum are continuously being refined and improved, so it is likely that in future these methods and solutions may be replaced with something more appropriate. None-the-less, we hope someone might find the information in this blog useful when implementing their own doors!