Inputs and Outputs
Inputs and outputs are useful to allow entities to trigger actions by other entities.
Entities have two methods for communication: sending an output to another entity, or receiving an input from another entity. One entity may send an output when it is killed to another entity's input which causes it to change color. That same output could also be used to trigger another entity's spawning input. The outputs are matched to the inputs via a connection, which controls what extra data is relayed to the receiver, how much of a delay there is before the output is received, and whether the output should be allowed to be sent again later. Outputs can be linked to any input and vice versa. This allows complex and powerful interactions between entities.
As an example, a
logic_timer entity may send an
OnTimer output, which triggers when the time condition is met for the entity. That output might be hooked to the
Show input on an
env_sprite, causing it to become visible when the timer has reached its desired time. You could also hook the
OnTimer output for the
logic_timer to a
SparkOnce input on an
env_spark to cause it to emit sparks. By using the connection properties, you could also cause the output to be triggered after a two second delay, or to trigger once but never again.
For users more familiar with the original Half-Life method of entity communication, the
target fields are now obsolete and the entity I/O system is a superset of that functionality. Instead of a
trigger_multiple entity only firing its target entity, it may now use any number of its outputs to do the same, including:
OnTouch, etc. These outputs may be connected to an arbitrary number of entities all at once with unique delays per output, making multi-managers obsolete as well. Likewise, the
killtarget field is now replaced by connecting an output to the
Kill input of another entity.
Outputs are events that are fired when an entity's state changes. This could be a timer reaching its end, a button being pressed or a door coming to a close. Any number of outputs can be specified by a programmer internally in an entity to trigger on any number of criteria. Specifying outputs is done in the Outputs tab in an entity's properties. The Ouputs tab of the Object Properties dialog displays all the outputs that are connected from this entity to other entities.
- Name of the output to be triggered.
- Name of the entity to receive the output (click an entity with Eye Dropper tool to paste its name here).
- Input on another entity that will receive the output. This is where you will choose what action on the target entity you want the output to activate. For instance, if you want a npc_combine_s soldier to rappel, you would use the BeginRappel input.
- Parameter override to use if data is accepted by the target input. Often this is a number used by the input function (see Inputs section below).
- Amount to delay sending the output (in seconds). 1/10th of a second is expressed as "0.1" seconds.
- Whether to fire the output once.
- OnTrigger - When this entity is triggered, it will fire this output.
- OnMapSpawn - When this map is loaded, this output will be fired.
- OnNewGame - When a new game is created, this output will be fired.
- OnLoadGame - When a saved game is loaded, this output will be fired.
Inputs connect to outputs of any type. Here we see the Inputs tab on the Object Properties dialog. It shows all of the outputs that are connected from other entities to this entity.
Because any output can connect to any input, there are a multitude of combinations that can be used to make complex interaction occur. Timers can orchestrate a countdown sequence using blinking sprites, sounds and special effects all without any need for special entities. By clicking the Mark button or double-clicking on an entry in the list, the user is able to go to the entity sending the output to the input in question.
If a connection is displayed in red, it is invalid. This means that either the output does not exist in the source entity, or the input is not present in the destination entity. Invalid connections are benign but should be fixed before map compilation because the Check For Problems menu command will report them as an error.
Outputs with values
Very few outputs give off values. A case of this is math_counter's OutValue output. These outputs are linked to inputs that take a parameter, and will fill in a value for that parameter when triggered. For example, on a math_counter there might be the following input:
OutValue mover SetPosition <none> where mover is a func_movelinear. The position of mover can then be changed through the simple arithmetic operations of the math_counter.
Setting up a simple trigger
This is an example of how to make a simple trigger using inputs and outputs, so a sound is played when the player enters a specific area.
Open up a map and add an ambient_generic (naming it "ambient_1"). Go into its properties and choose a sound file for it to play, and in its flags make sure it starts Off. Select the "toolstrigger" texture with the texture window and create a cube brush with this texture. Right click on this brush and using "Tie to Entity", make it a "trigger_once". Go to the outputs tab and click the "Add..." button.
For "My output named", select OnStartTouch. This causes the output (and thus the trigger) to occur when the player starts touching this brush in the game.
For "Targets entities named", select "ambient_1" using the pulldown arrow. This makes the trigger output target the ambient_generic you placed earlier.
For "Via this input", select "PlaySound". This chooses the PlaySound action from the target ambient_generic's list of actions, which of course causes its sound to start playing.
Click the "Apply" button to save your changes to the trigger, and close it. Now we have the trigger set up so that as soon as the player touches it, it sends a command to the ambient_generic which makes it start playing its sound.
If you open up the properties for the ambient_generic, you can see how the Output from the trigger has automatically been converted to an Input for an ambient generic.
If you want to compile and test your new trigger, make sure you have all the basics (player start, lighting, etc) and have assigned a sound effect to the ambient_generic!
Because the nature of how entities communicate has become more complex and powerful, so too has the debugging capabilities of the engine to help you track down problems. If a chain of I/O logic is not working as expected, the tools below will aid greatly in solving the error.
- By setting this console variable to a value of "2", you'll receive a detailed log of how the entities are interacting via the entity I/O system. This is useful for seeing the exact chain of events taking place in complex interactions.
- Setting this console variable to a value of "1" will display visual information about how entities are communicating with one another. This is very similar to using the developer console variable, but can sometimes be more immediately intuitive to the viewer.
ent_fire <entity name> <input name> <input value>
- This console command allows you to manually fire inputs on an entity from the console. This can be very useful for testing settings for entities in real-time. To fire the "Open" input for an entity named "testentity" with an input parameter of "3", you would type
ent_fire testentity open 3. You can also fire any entity that is under your crosshair using "!picker" as the entity name. More information in Targetname.
- This command pauses entities in the map. If entered again, the entities will resume their normal behavior. This is most useful when use with the
ent_stepcommand, described below.
ent_step <number of steps>
- When used with the
ent_pauseconsole command, this command allows the user to slowly step through an entity's chain of execution for input and output. Any number of steps can be iterated through at one time, as specified by a value entered after the command (i.e.
ent_step 3would execute three steps at once).