Wiring Source Engine Maps in Hammer Without Server Code
Wire Source Engine entities in Hammer so a button opens a door and plays a sound, without server code.
04 Jun 2026, 01:35 UTC

A button that does nothing
You place a func_button in a Hammer map, compile it, load the level, and press it. Nothing happens. The door nearby stays shut, no sound plays, and the console is silent. In Source Engine, entities do not interact automatically just because they sit near each other in the editor. You have to wire them.
The useful takeaway: Source Engine's entity input/output (I/O) system lets you connect events on one entity to actions on another entirely inside Hammer, without writing server code. It works for doors, sounds, lights, and branching logic, but it runs on the server's main thread, stays inside a single map, and fails silently if you mistype a target name.
How entity output and input wiring works
An entity is any object in the map with behavior: a button, a door, a sound emitter, or a logic controller. Each entity exposes named outputs (events it can fire) and named inputs (actions it can perform). In Hammer's Outputs tab, you map an output from one entity to an input on another, optionally adding a delay and a parameter value.
When the output fires, the engine passes activator and caller context. The activator is the entity that ultimately caused the event, often the player; the caller is the entity that sent the output. Some inputs use that context to decide what to do.
Worked example: button opens a door and plays a sound
This example uses Source 1 branch entities common in Half-Life 2-era games. Exact names differ by game, so check your game's FGD or SDK documentation before copying.
Entities to place in Hammer
| Entity | Name (targetname) | Role |
|---|---|---|
func_button | btn_door | Player-pressible trigger |
prop_door_rotating | door_main | Door that swings open |
ambient_generic | sound_door | Plays a door sound effect |
Outputs to configure on btn_door
- Output:
OnPressed; Target:door_main; Input:Open; Delay: 0; Parameter: empty - Output:
OnPressed; Target:sound_door; Input:PlaySound; Delay: 0.2; Parameter: empty
Where to run: Hammer, the Source map editor, on a Windows workstation with the game SDK installed. You need write access to the map folder. Compiling the map uses VBSP and related build tools; a failed compile leaves the previous BSP in place, so the safest rollback is to revert the VMF source file and recompile.
Verification
- Save the VMF and run the map compile.
- Load the map in-game and press
btn_door. - Confirm
door_mainswings open andsound_doorplays shortly after. - Open the compiled BSP in a BSP inspection tool and inspect the entity lump. The
btn_doorentity should carry anoutputskeyvalue listing theOnPressedconnections. Missing keyvalues mean the wiring did not survive compilation.
Risk: Hammer does not validate target names at compile time. Typing door_mian instead of door_main produces a working map that silently does nothing. Check entity names first, then watch the server console for missing-target warnings.
Trade-offs and limits
- Single map only. Entity I/O cannot cross map boundaries. Persistent state between levels requires save/load blocks or server-side code.
- Synchronous execution. Outputs run on the server's main game thread. A chain that fires every frame can cause server hitches; use rare events or logic timers instead of per-frame logic chains.
- Hard to debug at scale. Long chains of
logic_relayandlogic_caseentities are difficult to trace. Complex rules are usually clearer in server code. - Branch differences. Input and output names vary across Source 1 games and do not transfer directly to Source 2. Verify names for your specific game and engine branch.
When to wire in Hammer and when to write code
Use entity I/O for one-off map events: a button that opens a door, a trigger that plays a sound, a round-start relay that disables a spawn room door. Move to server-side plugins or scripts when you need cross-map persistence, per-frame logic, complex state machines, or detailed logging. A practical rule is to replace any logic chain longer than three relay entities with code.
Before you ship the map, press every wired button, check the compiled BSP entity lump, and watch the server console for missing-target warnings. If the door moves and the sound plays, the wiring survived compilation.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.