Chapter 2.4: Running Code with Entity I/O
Your scripts don't have to just run once. You can trigger code to run at any time using the game's built-in Input/Output (I/O) system.
All entities have these special VScript Inputs:
CallScriptFunction: Looks for a function by name within the entity's script and runs it. Best for calling pre-defined functions without arguments.RunScriptCode: Executes its parameter as a single line of Squirrel code. Best for simple commands or for calling functions that need arguments.
Example
Imagine a button (func_button) and a door (prop_dynamic). The door has a script attached to it called door_logic.nut.
door_logic.nut:
// Define a function inside the door's script scope.
function OpenTheDoor() {
printl("The OpenTheDoor function was called!")
EntFireByHandle(self, "Open", "", 0, null, null) // An example of what you might do.
}
function OpenTheDoorDelay(delay) {
EntFireByHandle(self, "Open", "", delay, null, null)
}
In Hammer, you would create an output on the button's OnPressed event. You have two options:
- Target the door and use the input
CallScriptFunctionwith a parameter ofOpenTheDoor. This is clean and simple. - Target the door and use the input
RunScriptCodewith a parameter ofOpenTheDoorDelay(3). This allows you to pass data directly into a function.
When the player presses the button, the corresponding function in your script runs.
The Actors: self, activator, and caller
When code is run via the I/O system, VScript provides special variables that tell you *who* is involved in the action.
self: The entity whose script is currently running. In the example above, `self` is the door.activator: The entity that initiated the entire chain of events. This is most often the player.caller: The entity that fired the *specific input* that triggered your script.
Visualizing the Chain
Imagine this setup: A player presses a **button**. The button's output targets a **trigger**. The trigger's output targets a **door**, which has a script on it.
activator
caller
self
// Inside the door's script function
function AnalyzeSignal() {
printl("I am the door: " + self.GetName()) // self is the door
printl("The signal came from: " + caller.GetClassname()) // caller is the trigger
printl("This was all started by: " + activator.GetClassname()) // activator is the player
}
Understanding this chain is vital for creating logic that correctly identifies who or what is interacting with your scripted entities.