Overview
This guide aims to demonstrate how to write simple VScripts for Contagion.
Introduction
VScripts are server-side scripts giving level designers access to various game functions. In Contagion, VScripts are written in the Squirrel programming language, and are used among other things, to control spawning of zombies and items, as well as sending objectives to the players cellphones.
- List of API functions
- VDC VScript article
- Squirrel reference manual[squirrel-lang.org]
- Notepad++ Squirrel syntax highligthing[forum.liberty-unleashed.co.uk]
[www.dropbox.com]
Creating and running scripts
VScripts are created using normal text files with the file extension .nut. For the game to find them, they are placed in the directory SteamSteamAppscommonContagioncontagionscriptsvscripts, and scriptsvscripts when packerd in the add-on VPK.
In this example, our VScript is called example_script.nut.
We start by creating a new text file, and changing the file extention to .nut. Make sure to have file extensions enabled in explorer. Then we add this simple code to our example script using our favorite text editor.
In Hammer, we add a logic_script entity to the map. This entity serves as a container for the VScript, and allows map entities to communicate with it.
In the entity properties, we add the script file name (without extension) to the VScripts keyvalue.
When we run the map, the script will automatically execute when the logic_script entity spawns, and print a Hello World message to the console.
Note that the message is printed before players have had time to load in or even spawn. For sending objectives to the players and spawning zombies, we will need a way to choose when to run the code.
Calling functions
To control when we run our code, we need to create functions, and then call them from the map when needed.
A function is made with the function keyword, followed by the function name, and a pair of parantheses with an optonal set of parameters between. Any code inside the function is wrapped between a pair of curly braces.
We make a function to be run after we load the map, and put it in the end of our script:
In the map, we create a logic_auto entity, an add an output to to our logic_script to run the function when them OnMapSpawn output fires.
After we compile and run the map, the function gets called by the logic_auto, and gives us some starting weapons, as well as a phone message.
Next, we’ll naturally want some zombies to test our weapons on, so lets create a button for spawning them.
First we add a new function to our script:
To call the function, we create a button out of brushes, and make it a func_button entity.
Now every time we press the button, we will have three zombes spawn in (make sure to have created a navigation mesh for your map, or the zombie will not spawn).
Objectives
In the Escape and Extraction game modes, we will need to create objectives for the survivors. Most of the work can be done either with normal entity logic in hammer, or with VScripts. However, we need to use a VScript to spawn zombies and sending messages to the survivors phones.
Phone messages are sent using two of the methods of The President: ThePresident.SendObjective(text) and ThePresident.SendObjectiveWithTarget(text, x, y ,z)
SendObjective takes a text string, and displays it on the phones as a message. SendObjectiveWithTarget also marks a position on the Extraction map, set by the x, y and z coordianates, as well as showing the distance to the position in other game modes.
We can also find the character name of the player closest to an entity, using the GetNearestPlayerName(entityName) function, allowing for more personalized messages. If we create a button like in the previous section, but give it the name mysterious_button and make it run the MysteriousButtonPressed() function, this code can be used to send a message with the button activators name.
To get our button to do anything we have a few options, we can send outputs from it directly, but we can also do it from within the VScript, using the DoEntFire() function. The function allows us to fire an entity output the same way it’s done in Hammer.
Lets make out mystery button open a metal shutter. For that we need two entities, a prop_dynamic with the shutter model, and a invisible func_door. We name the prop shutter_prop and the door shutter_door.
We then add entity outputs for opening the door and triggering the prop animation to our function:
Spawning items and zombies
There are several different ways to spawn items and zombies, and they are all done through the ThePresident handle.
The weapons players initially spawn with are set with the ThePresident.SetSpawnWeapon(<weapon slot number>, <weapon name>, < min random ammo>, <max random ammo>) method. The weapon slots are numbered from 0 to 3, and correspond to the four different weapons a player can carry at the same time. If the function is run multiple times with the same slot number, a weapon is randomly selected from the entries. The weapons to spawn are named the same as the corresponding entities, with the exception being the melee weapons, which are spawned without the weapon_ prefix.
Example:
Random weapons can be spawned with the ThePresident.CreateWeapon(<entity name>, <number to spawn>) method, to random info_random_weapon entities. Ammo and items can be spawn similarily with the ThePresident.CreateAmmo() and ThePresident.CreateItem() methods.
Example:
There are a few methods of spawning zombies. The first one is ThePresident.CreateZombies(<amount of zombies>), that simply spawns the specified number of zombies in any valid area. To specify the spawn area, the ThePresident.CreateZombiesArea(<amount of zombies>, <spawn area name>).
These functions only spawn a set of zombies when the function is called, but continious spawning can be done as well, using the ThePresident.CreateZombiesConstant(<amount of zombies>) method. After it has been called, it will keep spawning in zombies as they are killed, so the total amount of them stays the number specified.
Example:
Entity scripts
Even though the standard way to run scripts is through a logic_script entity, scripts can be run on any server-side entity. This feature is missing from the Hammer FGD file, so it is not visible in the keyvalue list by default. The keyvalues can be added manually with Smartedit turned off. The vscripts keyvalue sets the script file to use, and an optional thinkfunction keyvalue sets a function to be run every frame (0.1 seconds).