Valve Developer Union

How They Did It: Special Effects in Half-Life

(April 8, 2018)

(Community guide by Windawz, with information adapted from the Half-Life Red Alert site)


One of the most striking things about the original Half-Life was its use of special effects. Through clever use of entities and animations, Black Mesa felt less like a static game world and more real, more dangerous. The scripted sequences of equipment failures, mutated and mutilated scientists, and havoc-wreaking aliens catapulted Half-Life far beyond the games from which it spawned.

Though basic by today's standards, Half-Life still holds up well today in creating its cold, unfamiliar environments. This guide goes through a few memorable sights and scenes from the early game to explain how exactly Valve made it happen.

"Black Mesa Inbound"

c0a0a

Near the map spawn to the train's right, a hanging rocket shell sways lightly from the ceiling. The devs achieved this by tying the shell to func_pendulum. The shell swings 15 degrees back and forth at a moderate speed.

The rocket shell in-game The rocket shell in the editor
Left: The rocket shell in-game
Right: The rocket shell in the editor

c0a0d

Later on, Gordon briefly rides over a pool of toxic waste, with a huge tank dripping green waste off to the side. The waste is emitted by an env_shooter that uses sprites/flare3.spr for its projectiles. These are tinted green with the rendercolor keyvalue.

The leaky tank in-game The leaky tank in the editor, with a focus on the env_shooter's keyvalues
Left: The leaky tank in-game
Right: The leaky tank in the editor, with a focus on the env_shooter's keyvalues

"Anomalous Materials"

c1a0

An amusing bit of scripting comes early on, in the whiteboard room. If you turn the lights off, one of them will head to the switch and turn the lights back on. However, if you, after turning the lights off, turn them on again, the scientist will leave the lights on, though his walk script will still play.

Turning off the lights The entity setup for the lights
Left: Turning off the lights
Right: The entity setup for the lights

This setup works because, when the scientist reaches the switch, a scripted sequence is activated that makes him play an animation of pressing the button. A trigger_relay fires a few seconds after the scripted sequence is initiated. The relay targets a group of lights and it is also set to only turn them on, through the triggerstate keyvalue. This is why the scientist is only able to turn the lights on. (The scientist in this sequence is named bucky, if you're curious.)

Here he is
Here he is

"Unforeseen Consequences"

c1a1

After the disaster and during his escape, Gordon comes across a dead security guard who then gets mutilated by a laser. A gruesome scene, and one that was created without using a single security guard entity.

Guard sliced by a laser The entity setup for the dead security guard
Left: Guard sliced by a laser
Right: The entity setup for the dead security guard

The setup used two separate monster_generic entities set to the guard model and two scripted_sequence entities. Both are set to play the guard's laseridle sequence as their idle animation. When the laser hits a func_breakable hidden underneath the guard, the scripted_sequence entities quickly switch to their action animations, the two halves of the guard. Multiple gibshooter entities add additional gore to the scene.

c1a1b

There's a scene in this map where a vortigaunt breaks out of a small room. What's special about it is how the door changes its shape while being "hit" by the vortigaunt on the other side. The shape of the door doesn't really change; there are actually several doors—the original door that we see before the sequence starts and several other, deformed variants of it. Each door is a func_wall_toggle that get triggered, one after another, creating the appearance of deformation.

The vortigaunt breaking down the door All the different door models
Left: The vortigaunt breaking down the door
Right: All the different door models

At the end of the sequence, the door breaks entirely. Valve accomplished this using an invisible func_breakable. Not only does the breakable provide metal gibs and proper breaking sounds, it also prevents the player from getting stuck in the temporary doors until the sequence is over.

c1a1f

This map has probably one of the most memorable scenes in the whole game: a zombie having a seizure in the now-dark whiteboard room, with the only light coming from a strobing white laptop screen.

The strobe zombie The strobe zombie's keyvalues
Left: The strobe zombie
Right: The strobe zombie's keyvalues

The freak sequence is specified in a scripted_sequence as the zombie's idle animation. After you disturb the zombie somehow, either by hitting it with the crowbar or by breaking the laptop in front of it, the zombie finally stops twitching and dies. The same scripted_sequence is used here, with freakdie specified as the action animation. The scripted_sequence is activated either by the monster itself, firing the sequence when its health reaches 50%, or by breaking the laptop.

"Office Complex"

c1a2

After Gordon exits the elevator, he's flanked by a group of headcrabs that die violently by way of exposed wiring. This has the added bonus of letting the player know they can't progress that way without shutting the power off.

The lights frying a headcrab The setup of the hallway
Left: The lights frying a headcrab
Right: The setup of the hallway

In creating this sequence, the mapper placed several trigger_once entities directly in the paths of the headcrabs. After a headcrab reaches one of the triggers, an env_laser strikes it. The triggers are set to be activated only by monsters; a player-only trigger exists which plays a sound and instantly kills the player.

"We've Got Hostiles!"

c1a3

Everyone knows the scene at the start of this level; a guard is dragged into a vent by a zombie to be ripped apart and eaten with extreme cruelty.

A guard about to be grabbed The guard vent setup
Left: A guard about to be grabbed
Right: The guard vent setup

Both the guard's animation in this sequence and the zombie's animation are tuned to the brushwork of the room. After the guard disappears, several shots ring out. This is a good example of less being more. Aside from the initial scripted_sequence entities, the gunshot sounds are caused by an ambient_generic and the muzzle flashes are simply a light entity being toggled by a multi_manager. Simple effects, but creatively executed.

This is not an exhaustive list. Valve's level designers and modelers used similar tricks across the entire game to put together the effects and cinematics we got in the final product. It goes to show that a little detail applied well can go a long way into enhancing the realism of your level.