Sequencing Map Events with logic_relay in Source Engine Hammer
Wire one player action to multiple delayed events in Hammer using logic_relay, then verify the chain on a dedicated server.
13 Sept 2025, 19:45 UTC

The problem: one button, several delayed events
You place a button in a Hammer map. You want it to open a door, play a sound, and switch on a flickering light two seconds later. Writing server-side code for a single scripted sequence is overkill, and placing separate triggers for every event clutters the map. Source Engine maps can wire entities together directly in Hammer using entity input/output, or I/O: one entity’s output fires another entity’s input, with optional delays and parameters. The practical takeaway is that logic_relay acts as a programmable hub for this wiring, but a misspelled connection fails silently and multiplayer timing can desynchronize, so you should verify on a dedicated server before shipping.
How entity I/O works in Source Engine
An entity is any named object in a map, such as a door, light, or trigger volume. An output is an event an entity can broadcast, like OnTrigger when a player enters a volume. An input is an action an entity can perform, like Open on a door or PlaySound on an ambient sound. The activator is the entity that caused the chain, usually the player. The caller is the entity that fired the output. Outputs and inputs are case-sensitive and vary by game and SDK branch.
logic_relay does not do anything visible by itself. It exists to receive one input and fire many outputs, each with its own delay. That makes it the right tool when one player action needs to start several events at different times.
Worked example: sequence a door, sound, and light
This example assumes a Source 1 SDK branch and Hammer. Entity names are placeholders; replace them with your own.
- Create a trigger_multiple named trg_start where the player presses the button.
- Create a logic_relay named rly_sequence.
- Create a door named dr_hall, an ambient_generic named snd_alarm, and a light named lgt_flicker.
- In trg_start, add an output: OnTrigger targeting rly_sequence with input Trigger and delay 0.
- In rly_sequence, add outputs:
| Source | Output | Target | Input | Delay | Parameter |
|---|---|---|---|---|---|
| rly_sequence | OnTrigger | dr_hall | Open | 0 | |
| rly_sequence | OnTrigger | snd_alarm | PlaySound | 0 | |
| rly_sequence | OnTrigger | rly_sequence | User1 | 2 | |
| rly_sequence | OnUser1 | lgt_flicker | TurnOn | 0 |
The third row makes the relay call itself after two seconds, which then fires OnUser1 to turn on the light. You can also pass !activator or !caller as a parameter so one relay can target the entity that started the chain dynamically.
Verify the wiring before you publish
Compile the map with the SDK tools matching your target game branch. Start a listen server and open the developer console. To manually test the relay without walking into the trigger, run:
ent_fire rly_sequence Trigger
Where to run: the in-game console on a listen server, or the dedicated server console through RCON. Required permissions: sv_cheats 1 may be required on some branches, and RCON requires server administrator access. Expected check: the door opens, the sound plays, and the light turns on after roughly two seconds. If nothing happens, check the Hammer output spelling, compile log, and whether the entities were named exactly as wired.
Risk: ent_fire can run destructive inputs such as Kill, which removes an entity from the current session until the map restarts. Test with non-destructive inputs first.
For multiplayer maps, repeat the test on a dedicated server. Entity I/O executes on the server, while clients rely on prediction and interpolation, so scripted visual events can appear out of sync to players even when the server logic is correct.
Trade-offs and limits
- Misspelled or case-incorrect output and input names fail silently instead of reporting an error.
- Long chains of relays become difficult to debug; use logic_case for branching behavior instead of nesting relays.
- Timing differs between listen servers and dedicated servers; verify on a real dedicated server, not only local play.
- Source 2 and Hammer 2 use a different entity schema, so Source 1 names, outputs, and inputs do not transfer directly.
Ship it
Keep a backup copy of your .vmf before wiring complex chains so you can revert if the map behaves unexpectedly. Name entities with prefixes such as trg_, rly_, dr_, and lgt_ to make outputs easier to audit. Build one chain at a time, confirm it in the console, then test on both a listen server and a dedicated server. When the relay fires in the right order with the right delays, the sequence is ready for the map.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.