This article was originally published in PC Gamer UK 262, back in January 2014. It's reproduced here, for Half-Life's 20th anniversary, with author Robert Yang's permission.
20 years ago, Half-Life was released to a rapturous commercial and critical reception. It is a game about... well, it depends on who you ask. For some people it’s about Gordon Freeman, an everyman physicist who struggles to survive the inter-dimensional alien invasion of a secret government research facility. For others it’s about a mute sociopath who murders anything that moves, as he bunnyhops (always hopping) with bloodlust. More cynically, Half-Life is just another game about jumping on things and shooting things in the face to get to the next level.
But as a longtime Half-Life modder and game developer, I also know Half-Life in a very different way: in its map logic scripting, SDK source code, 3D models and animation events, 2D skins and texture flats—I’ve even studied the way Valve named the individual game files and folders. Game developers must make millions of small decisions all the time, and each decision is in conversation with a million other decisions. How big can a Half-Life level be, how many colours and shapes can it have, what can it look like? Well, it depends on how much texture memory and 3D map geometry memory you’re allocating in the engine. Half-Life’s guts influence what Half-Life can show you and what Half-Life can do.
And what Half-Life’s guts say is that everyone else is wrong. Half-Life is not a game about Black Mesa, Gordon Freeman, headshots or puzzles. Half-Life is fundamentally a game about... trains.
Black Mesa inbound
Half-Life begins with a seven-minute work commute. The Black Mesa facility swirls to life around your monorail: co-workers run late to work, forklifts rush through maintenance tunnels, an idling helicopter waits for passengers. It is an iconic and oft-imitated stretch of scene-setting.
The chapter was pitched initially as more of a tech demo than a bit of subtle atmosphere. According to former Valve writer Marc Laidlaw, it began when a programmer implemented a new type of game object called a ‘func_tracktrain’. Unlike its simpler ancestor func_train, inherited with the Quake-derived codebase, func_ tracktrain could run on a long stretch of path_track, branch onto different tracks, and bank and pivot into turns. To show off the new functionality, the programmer asked Laidlaw to write some use of func_tracktrain somewhere in the game. Laidlaw interpreted the request more literally and asked himself, what were the possibilities afforded by using a train?
1. Level crossing
Half-Life’s ﬁrst chapter is made of six different map ﬁles that load as you cross certain thresholds along the track route. At the time, Half-Life pioneered an innovative ‘seamless’ loading technology between map ﬁles without separate loading screens. The player could backtrack between maps and NPCs could even follow the player across level transitions. Today, many games implement some form of ‘level streaming’ where the engine begins slowly preloading new map data in the background as soon as the player is close enough to a transition point, thus drastically shrinking level load times. Half-Life didn’t have that, but it still used the technique to its advantage.
2. Parenting issues
The monorail tram ‘door’ is a fake door that is part of the tram wall and cannot open. The Half-Life engine did not support ‘entity parenting’, so designers could not glue or ‘parent’ a functioning door to the func_tracktrain of the tram. They couldn’t glue glass windows, other passengers, or even pieces of rubbish to it either. One workaround: start the player inside the tram already, so a functional door is not necessary.
To tell the func_tracktrain where it can go, the level designers placed a series of ‘path_track’ points. Each point had a unique name and the name of the next path_track in the sequence. When the func_tracktrain runs, it travels along these points in order and connects all the dots. If the train suddenly ﬂew off the track, that meant there was probably a typo in conﬁguring one of a hundred path_track points. It was tedious work.
To give the illusion of a ‘seamless’ level transition, two map ﬁles must share the same room. If a map ends with a dark section of concrete tunnel, then the next map must start with an identical copy of the concrete tunnel. However, it means that if the designers ever change that tunnel later, then they must also update the twin copy in the other map ﬁle, which can get messy and time consuming. Thus, transition areas in Half-Life are often featureless narrow hallways with few details.
How many megabytes of memory does your graphics card have? A few gigabytes? Back in 1998, game developers counted every megabyte: each map ﬁle in Half-Life was limited to two megabytes of texture memory. These days, a single shrubbery in the new Call of Duty probably uses two megabytes of texture memory, an entire Half-Life level’s worth by itself. Perhaps we’re too wasteful these days.
S-shaped bends and hallway-room-hallway structures were great line-of-sight blockers for ‘visibility culling’, where a game engine avoids wastefully drawing hidden scenery. Why spend precious cycles rendering something behind a wall? Valve designers had to pre-calculate a ‘potentially visible set’ (PVS) of which rooms can see into which rooms. If any walls got destroyed, it would become obsolete, which is one of the reasons few games have deformable worlds.
7. End of the Line
So the tram door was a fake door that couldn’t open, but at the end of the chapter, the security guard miraculously opens it. How? Valve’s hack was ingenious: when the train first arrives, the game seamlessly loads a new map file of the same exact room (see ‘Twins’) except it swaps out the old tram for a new func_tracktrain with a door-shaped hole in the side, and the moving door is actually another func_tracktrain. Who said trains always have to be train-shaped? This trick is legendary among Half-Life modders: how the Valve developers used one unrelated system to ﬁx a different system.
The Shark Cage
In the summer of 1997, Half-Life was essentially just a pile of random moments and encounters. Marc Laidlaw was hired as writer to sort through that pile of game content and bring some semblance of coherence to it, but by then much of the action had already been prototyped. Half-Life’s development history suggests that Valve were concerned less with story as a goal in itself and more with ferrying the player linearly from setpiece to setpiece, to sustain the thrill of constant movement and progression. Half-Life, itself, is a train.
The chapter ‘Apprehension’ is halfway through the Half-Life rollercoaster. In the middle of this dimly-lit ‘water level’ is a shark cage sequence ripped out of a monster movie. When the player enters the cage to pick up the crossbow, it plunges into a pool with an ‘ichthyosaur’ creature that circles menacingly before biting its prey in the face. Trains are surprisingly relevant here because, remember, trains do not necessarily look like trains.
When the player ﬁrst enters the room, they set off a trigger_once that makes the monster_ichthyosaur perform a scripted_sequence to jump out of the water and devour a screaming monster_scientist. The jumping movement of the animation draws the player’s eyes upward, toward the suspended shark cage and balcony. To continue, the player must walk along a platform all the way around the cage, thus viewing it from all sides and likely noticing the crossbow weapon inside.
2. Node graph
NPCs in Half-Life are a lot like trains, they mostly go where the track leads them. But instead of a path_track, a designer must place info_node points that automatically link with nearby nodes into a web-like ‘node graph’. To pathﬁnd somewhere, the AI will look at all the different links between nodes to assemble its route. Here, Valve put many of the ichy’s waypoints underneath the cover of the catwalk, to discourage the player from freely sniping at the monster from above water. Good node graphs are often the difference between AI looking dumb or clever in any game.
3. Pickup bait
The crossbow comes with only ﬁve bolts. Killing the ichthyosaur on easy or medium mode requires four, and on hard mode it is eight. That means the player can only miss one shot with a weapon they’ve never used, against a monster they’ve never fought. To make it easier, the player solves a slightly earlier simple puzzle for some valuable MP5 alt-ﬁre grenades—which are useless against the ichy, but act as bait to trick the player into picking up 20 extra bolts for a weapon they don’t even possess yet.
4. The cage
The centrepiece of this room is a shark cage containing a crossbow, suspended from the balcony. When the player walks along the beam and drops down into the cage, it breaks and falls into the water. The cage is actually a func_tracktrain, running on a series of path_track points that guide the ‘cage train’ downward at roughly 6.5 metres a second.
5. The Gate
Once in the water, the player’s ultimate goal is to open this rusty gate to get to the next room. However, the rusty wheel turns very slowly and the player must hold down the ‘use’ key the entire time or else the gate will close by itself. It takes 12 seconds to completely open the gate—the exact same length of time that Gordon Freeman can hold his breath. All this is probably too difﬁcult to do while fending off the ichthyosaur; thus, indirectly, the game forces you to kill it ﬁrst.
...or at least that was the intent. Playtesters probably managed to open the door for only 6-8 seconds and then quickly slip through the gap, despite the roving shark monsters trying to kill them. To prevent that from happening, Valve added an invisible trigger in front of the gate wheel, which instantly alerts the ichthyosaur to the player’s presence and slams it into combat mode. This is technically cheating on the developers’ part, but it’s only cheating if you get caught.
6. Flying shark
The code for the monster_ichthyosaur is actually based on the same code used for ﬂying monsters. After all, what is swimming but ﬂying underwater? So if NPCs are actually trains (see ‘Node Graph’), then we can think of the ichy as simply a mindless homicidal ﬂying shark-train.
7. Bubble fun
Given the superb drownability of water in Half-Life, every second spent beneath its surface counts. To help the player navigate, even in foggy and murky waters, Valve used columns of bright bubble particles ﬂowing up, because the human eye is typically drawn to movement. They used these bubbles frequently in underwater sections to highlight tunnels, passages, or pockets where the player could surface for air.