Tutorial: Airlock system (that works in multiplayer) Last edited 3 weeks ago2024-11-08 09:41:44 UTC

Half-Life singleplayer uses airlocks a few times. You open the door, go into the airlock room and press the button. Then the door behind you locks and the door in front of you opens. This is easy enough to make, when it is just one player. It becomes more complex when you have to consider other players who can also use the buttons in and outside the airlock while others are inside the airlock.

One crucial part is that you need control over whether a door closes or opens. Ironicly enough, the func_door entity can't do this. It only supports TOGGLE mode. This means when triggered, it will close when it's currently open OR open when it's currently closed. There is no Only Open or Only Close option here.

The only way to have fine control over an entity is to use a trigger_relay, because it can be set to send an OFF or ON signal. There are only a few entities that support this. One of them is func_plat. It's a movable platform that we can also use as a door!

The Setup

First, create 3 rooms separated by 2 doors. Each room needs a func_button, 3 in total. Put your info_player_start on either side of the airlock. We'll set up the system that it can be approached from both sides and still work. For this, both doors will start closed.
User posted image

The Doors

As mentioned, turn the doors into func_plat. Give the door a name (door1) and set up the direction. For func_plat you'll have to set the travel distance. My door is 96 units high and should travel UP. I want it to have a lip of 4, so I'm setting it to -92. Set up the other door in the same fashion but with a different name (door2).
User posted image
Create 4 trigger_relay entities: We're using these to have fine control over the doors.

The Buttons

We'll set up the func_button next to door1 first: Put a multi_manager there with the following values: Then next to door2:
func_button: multi_manager:

The Airlock

You've noticed that the multi_managers trigger an 'airlock_mode'. This is something we'll have to setup next to the button inside the airlock. This will determine if we close door1 first and then open door2 or the other way around: close door2 first, then open door1. It will depend from which way we entered the airlock.

Let's set up the button inside the airlock.

func_button: Notice how this button currently has no target. We'll need to set up a dynamic target system with two trigger_changetarget entities and two multi_managers.

trigger_changetarget: trigger_changetarget: multi_manager: multi_manager: With this system, the airlock button will be set in the right mode depending on if you've entered from door1 or door2 first. After that it will toggle between both modes after each use.

The Problem

func_plat has served us greatly but it has one major flaw: it only deals 1 damage on blocked. This way players can cheat the system and keep both doors opened. The system will reset itself once a button has been used, so this can be a minor issue. However, if you map relies on those doors staying closed, we'll have to get creative.

The only entity that supports ON/OFF and deals damage is the env_beam (or env_laser). Put 2 info_targets between the door frame and name them 'beam1_start' and 'beam1_end'.
User posted image
Now set up an env_beam. These settings will make it invisible and kill a player on touch. We want the beam to turn ON once door1 closes and turn OFF when door1 opens. The env_beam starts OFF by default, so we'll have to create new trigger_relays and swap the trigger states:

trigger_relay: You can set up another env_beam for door2 in the same fashion. This should now fix our issue with players blocking the doors.

The Timings

If your doors are larger or faster/slower be certain to tweak the timings or the delays. My func_buttons all have a delay of 3 because the multi_managers trigger everything within 2 seconds. The doors also take just 1 second to close/open. If you use slow doors, you might also consider setting a small delay to the env_beam being set to ON.

The Download

A prefab of this system can be downloaded here.

2 Comments

Commented 3 weeks ago2024-11-08 13:35:30 UTC Comment #106493
Cool!
IMHO, simpler option:
  • two func_door (door1, door2): speed - 50, lip - 4, toggle;
  • trigger_changetarget (door1) to change the target of func_button (airlock_button) to multimanager (a_but2);
  • trigger_changetarget (door2) to change the target of func_button (airlock_button) to multimanager (a_but1);
  • multimanager (a_but1): door1 - 0, door2 - 2;
  • multimanager (a_but2): door1 - 2, door2 - 0;
  • button (on right side, near info_player_start): target - door1;
  • buttun (on the left side): target - door2;
  • button in the middle (airlock_button), target - (empty).
Commented 3 weeks ago2024-11-09 14:08:30 UTC Comment #106495
@man_simple

Your setup works well for singleplayer but not for multiplayer. The button for door1 and door2 can be pressed by seperate players, which then opens both doors. Now that both are open and func_door can only TOGGLE, your airlock is broken forever. You would have to create a eleborate system of multisources to lock the buttons to prevent this. Even then, a player can block the door by crouching under it and the game would never know that the door is now not closed. Which again breaks the entire system.

You must log in to post a comment. You can login or register a new account.