Script Authoring

From EventScripts Community Encyclopedia

Script Pack Authoring

This guide is a quick walkthrough of how to get started writing script packs.

--> Note: This guide is rather out-dated. It references writing "script packs" which are a little old. "Script addons" are more powerful and sometimes easier to use.

It assumes you already have EventScripts installed and running on your server, and that you have direct access to your server for uploading files. This file is also somewhat directed at CS:S scripting, but applies to any use of EventScripts.


This will walk you through creating your first script and give you functional examples as well as a few helpful tips for writing with EventScripts. If you read this in its entirety you will not only have a good idea of how to code what is shown here with EventScripts, but also have a functional understanding of how it works so you can formulate your own original scripting.




How Eventscripts Works

EventScripts is an interface between you and the Source engine.

The Source engine is used in Counter-Strike: Source, Half-Life 2, Half-Life 2: Deathmatch, Day of Defeat: Source, and several other games. It is what powers the visuals you see, the sounds you hear, your interaction with the environment, and the game itself.

There are some things that happen consistently in the game that are based on the player's interaction with the game or the game's interaction with a player. These are called 'events'. Events caused by players are things like dying, firing a weapon, jumping, or even sending a chat message. Events caused by the game are things like a map changing due to a time limit, a round starting, a round ending, or timer running out on a bomb.


EventScripts allows you to tell the game what to do when any of these kinds of events occur.


The easiest way to understand EventScripts and get started making your first script is to think of it like you're talking to the game about something you want.

For example, if you wanted to send a player a message when they die, you would tell the game "When the player dies, tell him he sucks." Or, maybe you want something more complex like, "When the player dies, tell him who killed him and how much health they have left." In both of these cases, the player dying is the catalyst for the scripting - it is the 'event' that triggers what you're trying to accomplish.


If that sounds simple, it's because it is. Thanks to EventScripts, you don't need to be a programmer to talk to the game anymore - you can talk to EventScripts and let it tell the game what to do.




Let's start by taking a look at some of the more commonly-used events you can tell the game to do things for. By the end of this guide you will be able to write basic scripts for all of these:


Common Player-Triggered Events:

1. player_activate

  • Triggers when a player has connected, fully loaded the map, and is shown the MOTD.
    • Example: "When a player is connected and loaded, tell everyone they're ready for battle."


2. player_spawn

  • Triggers every time a player spawns (at the beginning of the round or when they are spawned in DeathMatch)
    • Example: "When the player spawns, give him a free HE grenade."


3. player_death

  • Triggers every time a player dies for any reason (slayed, killed by another player, etc.)
    • Example: "When a player dies, tell the player who killed them and how much health they have left."


4. player_disconnect

  • Triggers every time a player disconnects from the server for any reason (kicked, quits, loses connection, etc.)
    • Example: "Whenever a player leaves, tell everyone in the middle of the screen that they're leaving the server."


Player-Triggered events are powerful because they carry a LOT of information. This information is stored in 'event variables'. Think of 'event variables' as the who, what, when, where, why, and how of an event.

For example, when a player dies, there are some questions you might ask:

  • "Who killed them?"
  • "What weapon were they using?"
  • "What was their name?"
  • "How much health did their attacker have?"


These are called 'event variables'. Some of the basic information carried with a player-related event, such as a death, is listed below:

  • userid <-- UserID of the player
  • es_username <-- Name of the player
  • es_userhealth <-- Health of the player
  • attacker <-- UserID of the attacker, if the event involves an attacker
  • es_attackername <-- Name of the attacker, if the event involves an attacker
  • es_attackerhealth <-- Health of the attacker, if the event involves an attacker


Common Game-Triggered Events:


5. round_start

  • Triggers every time a new round starts
    • Example: "Whenever the round starts, tell people the IP of the server so they don't keep asking."


6. es_map_start

  • A special event made for EventScripts that triggers when the map has fully loaded on the server
    • Example: "Whenever a map starts, check to see if it's de_port and if it is make the c4 timer 45 seconds so CT's actually have a chance. Also check to see if it's de_dust and if it is, put the c4 timer at 25 seconds to help the T's."


7. round_end

  • Triggers every time a round ends for any reason (objective is completed, one team's players are all dead, round draw, etc.)
    • Example: "Whenever the round ends, if a team failed an objective take $1000 from players on that team."




Create Your First Scripts


We'll do these in order, as they've been set up to get harder down the list. The first one is very simple.


1. player_activate

  • Triggers when a player has connected, fully loaded the map, and is shown the MOTD.
    • Example: "When a player is connected and loaded, tell everyone they're ready for battle."


  • First we need to create a place on your system to hold all of your event scripts:
    • Start by creating an events directory on your computer that you can use to organize your files. On your server, this directory is (by default) at cstrike/cfg/events - however, this directory may not exist if you haven't uploaded anything yet.
    • Once you have your events folder, create a new text file in it and label it:
player_activate.cfg

Make sure that the extension is actually .cfg - Windows by default will not show you the extention, and it will remain a .txt file. If this is the case, turn off 'hide extensions for known filetypes' option in Tools>Folder Options>View. If you're not sure, check that setting - it's critical to get the .cfg extention.


Now that you have player_activate.cfg, EventScripts has a job to do. EventScripts will listen to anything you put in that file. Let's start by accomplishing our goal: "When a player is connected and loaded, tell everyone they're ready for battle."


The first thing we need to do is learn a command:

es_msg [color] <message>

es_msg allows you to send text that shows up in the chat area of the screen in either yellow (default), green (#green), or light green (#lightgreen).


For example, if we wanted to say, "Hello, world!" - I'd use:

es_msg Hello, world!


...or if we wanted to say it in green, we would use:

es_msg #green Hello, world!


Very simple, and very easy to use. Now all we have to do is tell EventScripts to use it in the file:


In file player_activate.cfg:

es_msg #green Hello, world!


...but why not put something useful in there? Remember, our goal is to tell the server, "When a player is connected and loaded, tell everyone they're ready for battle."


We already know player_activate.cfg has everything the server will do when a player is connected and ready to play, so instead of "Hello, world!", we write:


In file player_activate.cfg:

es_msg #green Player _________ is ready for battle!


You'll notice a blank in there. All we need to do now is fill it in with the player's name - but since different players will be connecting, we need to tell EventScripts to fill in the blank for us.


Remember the 'event variables' from earlier? es_username is one of them - and since this is a player-triggered event, we have the ability to make EventScripts 'fill in the blank' for us with their name.


So how does EventScripts know what we want it to do? Here comes another command you have to learn:


event_var( ) is our way of telling EventScripts to fill in the blanks - all we have to do is tell it what information to use. In this case, we want the player's user name, so we need to use the event variable 'es_username'. When you put it together, it looks like this:

event_var(es_username)


Knowing this, all we need to do is replace the blank from our last message with the 'event variable' EventScripts will use when it's filling in the blank. So we write this:

In file player_activate.cfg:

es_msg #green Player event_var(es_username) is ready for battle!

...and we just told EventScripts we want it to 'fill in the blank' for us by putting the player's username where we wrote 'event_var(es_username)'.


The final output will look like this in the chat area of the game:

Player Faaip is ready for battle!


If you want, you can save and upload that file into your 'cstrike/cfg/events' folder right now and see it happen in-game. What you learned making this script will make everything else you do here significantly easier - there's really nothing left to learn but commands.



2. player_spawn

  • Triggers every time a player spawns (at the beginning of the round or when they are spawned in DeathMatch)
    • Example: "When the player spawns, give him a free HE grenade."


To start, create a player_spawn.cfg file in your events folder, then open that file.


Open the file, and get ready to learn a new command:

es_give <userid> <entity>

This command allows you to give anyone in the server (userid) any weapon (entity).

For example, if we were to type this in the server's console:

es_give 320 weapon_ak47

...it would give the player with the UserID of 320 an AK47.

We're trying to give our players an HE Grenade when they spawn, so we'll use 'weapon_hegrenade'.


Remember, since we don't know what the UserID of the player will be when they spawn, we have to tell EventScripts to 'fill in the blank' for us.

Start by writing the command with an actual blank to make it easy for us to see what we're doing:


In file player_spawn.cfg:

es_give _____ weapon_hegrenade


Now that we have that, all we have to do is tell EventScripts to 'fill in the blank'. We have to use 'event_var( )' again, but this time we want to fill in the UserID of the player. So we'll use 'event_var(userid)':

In file player_spawn.cfg:

es_give event_var(userid) weapon_hegrenade


...and we just told EventScripts we want it to 'fill in the blank' for us by putting the player's UserID where we wrote 'event_var(userid)'.


The final result is that every time a players spawn, they will get a free HE Grenade.


If you want, you can save and upload that file into your 'cstrike/cfg/events' folder right now and see it happen in-game.



3. player_death

  • Triggers every time a player dies for any reason (slayed, killed by another player, etc.)
    • Example: "When a player dies, tell the player who killed them and how much health they have left."


This one is more complex, but only because we're having EventScripts fill in multiple blanks. It only uses one command you haven't already done in the previous two scripts.


Start by creating and opening player_death.cfg in your events directory.


Next, we have a new command to learn! Hooray!

es_tell <userid> [color] <message>


This command is JUST like es_msg, except that it will only tell one person (userid) the message. One thing to remember is that just like with es_msg, using a color is optional. We're going to skip using a color so that the text shows up yellow.


This time we're going to have a few blanks to fill in, so let's write out our message with actual blanks to make things eaiser:

In file player_death.cfg:

es_tell _____ You were killed by ______ who has ______ health left!


We have 3 blanks to fill in: The UserID we want to see the message, the person who killed them, and how much health their killer has left.


We've already had EventScripts fill in a UserID, so we'll start with that:

In file player_death.cfg

>es_tell event_var(userid) You were killed by _____ who has ____ health left!


Next, we'll fill in the attacker's name. We've already used the event variable 'es_username' - this is just like that, only we want to use 'es_attackername':

In file player_death.cfg

es_tell event_var(userid) You were killed by event_var(es_attackername) who has ____ health left!


Almost there - now all we need to do is tell EventScripts to fill in their health. This event variable is called 'es_attackerhealth' - so our final file looks like this:

In file player_death.cfg

es_tell event_var(userid) You were killed by event_var(es_attackername) who has event_var(es_attackerhealth) health left!


The final output will look like this in the chat area of the game when you die:

You were killed by Faaip who has 100 health left!


If you want, you can save and upload that file into your 'cstrike/cfg/events' folder right now and see it happen in-game.



4. player_disconnect

  • Triggers every time a player disconnects from the server for any reason (kicked, quits, loses connection, etc.)
    • Example: "Whenever a player leaves, tell everyone in the middle of the screen that they're leaving the server."


This one is very simple, and uses a new command that you'll find very handy:

es_delayed <time in seconds> <command>


'es_delayed' allows you to execute a command a specified amount of time later. For example, if I used:

es_msg #green Hello, world!
 
es_delayed 3 es_msg #green Greetings from Earth!


...then "Greetings from Earth" would show up 3 seconds after "Hello, world!".

This is handy for a lot of things - and allows a floating value, so you can do things like this (requires Mani Admin Plugin):

es_delayed .1 ma_slap event_var(userid)
es_delayed .2 ma_slap event_var(userid)
es_delayed .3 ma_slap event_var(userid)

...which would slap the player with the UserID 3 times in less than half a second.


Our purpose for this is to use it to work around a problem with displaying text in the middle of the screen. Since we want to tell everyone when a player is leaving, we'll have to use a new command:

es_centermsg <message>

es_centermsg is exactly like es_msg except that it doesn't support colors (text is always white), and you need to keep your message length relatively short - usually around 5 or 6 words fits well. It also only displays the message for ONE second at a time.


So let's get to building our script. Start by creating and opening player_disconnect.cfg in your events folder.

Then, write out the script as you want it to appear but use blanks where we want EventScripts to fill in the blank:

In file player_disconnect.cfg:

es_centermsg ________ ran away from the battle!


We want EventScripts to fill in their name, which we've alredy done before using the event variable 'es_username', so we write it:

In file player_disconnect.cfg:

es_centermsg event_var(es_username) ran away from the battle!


...but unfortunately here's where it gets tricky. Since es_centermsg only shows the text for 1 second, we want EventScripts to repeat the message a few times so that it displays long enough for people to actually read. This is where es_delayed comes in handy. We'll go for 5 seconds of display time, so we need to display the message once as we already have:

In file player_disconnect.cfg

es_centermsg event_var(es_username) ran away from the battle!

...then repeat a second later using the same command right after es_delayed 1:

In file player_disconnect.cfg

es_centermsg event_var(es_username) ran away from the battle!
es_delayed 1 es_centermsg event_var(es_username) ran away from the battle!

...and since we're going for 5 seconds we'll need to do this a few more times:

In file player_disconnect.cfg

es_centermsg event_var(es_username) ran away from the battle!
es_delayed 1 es_centermsg event_var(es_username) ran away from the battle!
es_delayed 2 es_centermsg event_var(es_username) ran away from the battle!
es_delayed 3 es_centermsg event_var(es_username) ran away from the battle!
es_delayed 4 es_centermsg event_var(es_username) ran away from the battle!


Now the command will be executed once every second for 5. Don't be confused by only getting up to 'es_delayed 4' - remember, the command 'es_centermsg' displays the text for 1 more second.


The final output will look like this in white text centered in the middle of everyone's screen for 5 seconds:

Faaip ran away from the battle!


If you want, you can save and upload that file into your 'cstrike/cfg/events' folder right now and see it happen in-game.



5. round_start

  • Triggers every time a new round starts
    • Example: "Whenever the round starts, tell people the IP of the server so they don't keep asking."


You already know what variables are - we've been using them to tell EventScripts to fill in the blanks for us. This is no different - but now in addition to using an 'event variable', we'll be using a 'server variable'.

Event variables used 'event_var( )' and allowed us to use information about the event. Server variables are very similar - they just use 'server_var( )' and allow us to use information about the server.


For example, a server variable you already know is 'mp_c4timer'. You can set this to any number, and it will change how long the C4 takes to detonate.

If you wanted to use this in EventScripts, you could use:

es_msg The bomb timer is at server_var(mp_c4timer) seconds.

If your mp_c4timer was set to "30", this would show everyone:

The bomb timer is at 30 seconds


Our goal here is to tell the server, "Whenever the round starts, tell people the IP of the server so they don't keep asking."

So we just need a server variable that has the IP of the server in it. Fortunately, there is such a variable: 'ip'. The same way we access a player's name in a player event with event_var(es_username), you can access the server variable for IP with 'server_var(ip)'.


Create and open round_start.cfg from your events directory.

Then, write out the line with blanks where you don't know the information:

In file round_start.cfg:

es_msg #lightgreen Welcome to the best server ever. Our server IP is _________

...now just add in the 'server variable' for the IP address, which is 'ip':

In file round_start.cfg:

es_msg #lightgreen Welcome to the best server ever. Our server IP is server_var(ip)


The final output appears in light green text in the chat area:

Welcome to the best server ever. Our server IP is 1.2.3.4


Server variables are very useful, but people tend to get event_var( )'s and server_var( )'s confused. Just remember that if you're getting information about an event, use 'event_var( )'. If you're getting information about something stored by the server, use 'server_var( )'.


If you want, you can save and upload that file into your 'cstrike/cfg/events' folder right now and see it happen in-game.



6. es_map_start

  • A special event made for EventScripts that triggers when the map has fully loaded on the server
    • Example: "Whenever a map starts, check to see if it's de_port and if it is make the c4 timer 45 seconds so CT's actually have a chance. Also check to see if it's de_dust and if it is, put the c4 timer at 25 seconds to help the T's."


Now we're getting to the good stuff. Create and open es_map_start.cfg from your events directory.


This next command is the most powerful command in EventScripts and programming in general:

if

...that's it. The syntax is going to make this look difficult at first, but it's extremely easy:

if (<variable1> <condition> <variable2>) then <command>


You've alrady used variables quite a bit (remember event_var(es_username)?), but the condition is new. Conditions are things like less than, greater than, equal to, etc. that allow you to compare 'variable1' to 'variable2'.


The first part of what we're going for is, "Whenever a map starts, check to see if it's de_port and if it is make the c4 timer 45 seconds so CT's actually have a chance."

So since we know we want to see if the map is equal to de_port, start by filling that in and using blanks where variables go:

In file es_map_start.cfg:

if (_________ equalto _________) then


Since we're trying to compare the current map to the one we want, we can fill in the blank for the map we want:

In file es_map_start.cfg:

if (_________ equalto "de_port") then


...and we also know that if the current map is equal to de_port, we want to change the C4 timer to 45 seconds:

In file es_map_start.cfg:

if (_________ equalto "de_port") then mp_c4timer 45


...which leaves us with one blank. Since we don't know what map the server is going to be on when this script runs, this is where we need to use a 'server variable' to have EventScripts fill in the blank for us.

EventScripts actually has a server variable called 'eventscripts_currentmap' that holds the current map. Remember, it's a server variable so instead of event_var( ) we have to use server_var( ):

In file es_map_start.cfg:

if (server_var(eventscripts_currentmap) equalto "de_port") then mp_c4timer 45


...and that's it! EventScripts will fill in the blank with whatever the current map is, and if it is equal to "de_port", it will set the C4 timer to 45 seconds.


Now let's do the same thing for de_dust, but we'll set the timer to 25 seconds because it's such a small map:

In file es_map_start.cfg:

if (server_var(eventscripts_currentmap) equalto "de_port") then mp_c4timer 45
if (server_var(eventscripts_currentmap) equalto "de_dust") then mp_c4timer 25


Again, EventScripts will fill in the blanks for the current map.

The last thing you need to do is make sure that the C4 Timer isn't always stuck on whatever we set it to last here. This would happen if you don't have mp_c4timer defined in your server.cfg. Most people do, but we'll write it in here just to be safe, and to keep this from happening:

-Server goes to de_port and gets C4 timer set to 45 seconds -Server changes maps to de_chateau and timer is still set to 45 seconds - d'oh!


So add this line and it will set the C4 timer before the rest of the script executes so that if none of the conditions are met it will have the default C4 timer value set:

In file es_map_start.cfg:

mp_c4timer 30
if (server_var(eventscripts_currentmap) equalto "de_port") then mp_c4timer 45
if (server_var(eventscripts_currentmap) equalto "de_dust") then mp_c4timer 25


The file will execute as follows:

  • The c4 timer will be set to 30 seconds
  • If the current map is de_port, it will set the c4 timer to 45 seconds
  • If the current map is de_dust, it will set the c4 timer to 25 seconds


If you want, you can save and upload that file into your 'cstrike/cfg/events' folder right now and see it happen in-game.


---

7. round_end

  • Triggers every time a round ends for any reason (objective is completed, one team's players are all dead, round draw, etc.)
    • Example: "Whenever the round ends, if a team failed an objective take $1000 from players on that team."


Now it's time for you to figure one out somewhat by yourself. Here's the code for the example, but I'm not going to explain every little detail - by now you should know what you need to sort through this entire script and know what every line means and the function it performs.

You'll notice what is called 'commenting' in the code - these are lines that are not seen by EventScripts, but are useful to document what we're doing in the script itself. You can comment by using two forward-slashes on a line you do not want EventScripts to see.

This script also requires Mani Admin Plugin


Good luck!


In file round_end.cfg:

// Target bombed
if (event_var(reason) equalto "1") then es ma_takecash #ct 1000
 
// Bomb defused
if (event_var(reason) equalto "7") then ma_takecash #t 1000
 
// Hostages rescued
if (event_var(reason) equalto "11") then ma_takecash #t 1000
 
// Bomb target saved (time ran out on a DE map)
if (event_var(reason) equalto "12") then ma_takecash #t 1000
 
// Hostages not rescued (time ran out on a CS map)
if (event_var(reason) equalto "13") then ma_takecash #ct 1000



If you get stuck, you can use these references (staples of the EventScripts community):


Use (and bookmark) this excellent reference to see what event variables are being expanded.


Check this forum topic for a complete list of events and EventScripts commands from the latest official version of EventScripts.


Hopefully you understand the basic idea of what this script does - you'll have to use the references to get specific knowledge on a couple things. If you want, you can save and upload that file into your 'cstrike/cfg/events' folder right now and see it happen in-game.



--Faaip 02:07, 17 July 2006 (EDT)



Documentation for EventScripts (scroll down for detailed description):

For now, take a look over examples in the forums here:

You should browse the Variable Reference and the Command Reference.

If you find you have problems with your script, visit:

blog comments powered by Disqus