VIP

New GameMaps in development!

x

We are working hard to bring you the best experience possible with our upcoming relaunch!

You can help fund the relaunch by
Upgrading to VIP or Donating.

  • VIP Goal Progress: 100% Goal Reached!
  • Top Donator: Anonymous ($1,000)
Left 4 Dead 2
Left 4 Dead 2 is a single-player and multiplayer co-operative survival horror FPS game.
VSLib Developer Guide
3,550
THE DEVELOPER GUIDE
Let's build.
Guide Contents
Introduction
VSLib (VScript Library) is a simple, lightweight library for L4D2's VScript mutation system. It is a loose collection of classes, functions, and tables that work together to provide additional features. VSLib is designed to be re-usable and easily updatable. Taking advantage of the entire library requires the programmer (that's you) to add only a single line of code!
Tank color changed with tank.InputColor(255, 0, 0);
Features
VSLib includes:

Synchronous timer system: Those who have coded plugins for SourceMod know about SM's powerful timer system. VSLib introduces the same kind of timer system: delayed function calls, repeatability, and argument support. The timer system allows the modder to fire a function (with any arguments) after a delay.

Entity class: Provides many new functions for entities, such as Ignite(), AttachParticle(), Hurt(), Kill(), GetTeam(), etc etc.

Player class: Builds on the Entity class to provide many more functions for survivor/infected entities: SetFlashlight(), GetSteamID(), GetIPAddress(), GetName(), etc.

EasyLogic system: As the name suggests, this table helps simplify the implementation of logic. Things such as ChatTriggers, save data, and game event notifications are managed by this table.

Utils table: Random but helpful utility functions.

HUD class: A collection of numerous HUD types.


Let's take a closer look.
Synchronous Timer System
Creating delays can become tedious. VSLib offers an easy solution.
// We want this function to fire 10 seconds later
function foo ( paramTable )
{
}

// So we can do the following from anywhere we want:

// AddTimer ( delay, repeat, funcToCall, optionalParams )
Timers.AddTimer ( 10.0, false, foo, someParamsHere );
That's it. You will learn a lot more about timers in the Timers chapter. VSLib timers can be made to repeat (i.e. fire every interval) and can be made to fire as little as 0.1 seconds later (unlike Update(), which only fires every second, VSLib timers can be made to fire in a fraction of a second). Internally, VSLib timers run as an injected Think() function.
Entity and Player classes
The Entity and Player classes provide many more functions. The purpose of these classes is to simplify the management of entities and players. Instead of having to code complicated and/or routine functions over and over again for each project, VSLib categorizes them in an object oriented, reusable fashion. Suppose you wanted to detect if a soccer ball is in the air. If you have a soccer ball with a targetname soccer_ball:
Entity ball ( "soccer_ball" );

if ( ball.IsEntityInAir() )
{
	// do something
}
You save the headache of having to code common functions over and over again for every new project. Moreover, there are over 100 functions in the VSLib Entity class that do various things. The Player class builds on the Entity class and provides many more player-related functions such as GetSteamID(), GetSpawnLocation(), etc. Both classes automatically and implicitly check for entity validity so the developer does not have to worry about crashing the game. This allows you to focus on coding your mutation / campaign instead of having to worry about trivial things!
The EasyLogic Table
Notifications

VSLib.EasyLogic includes a number of different things that are all under the "easy logic" umbrella. Everything in the EasyLogic table is an attempt to make logic implementation simpler. As the name suggests, EasyLogic is designed to be simple. Here's a side-by-side view of regular code to VSLib code (both do the exact same thing):

Normal VScripts
function OnGameEvent_player_now_it ( params )
{
	if ( params["userid"] != null && params["userid"] != "" )
	{
		local victim = GetPlayerFromUserID( params["userid"] );
		
		if ( victim != null && victim.IsValid() )
		{
			local name = GetCharacterDisplayName(victim);
			Say( null, name + " was vomited on!", false );
		}
	}
}
VSLib code
function Notifications::OnPlayerVomited::NotifyEveryoneBro ( victim, boomer, params )
{
	Utils.SayToAll( "%s was vomited on!", victim.GetName() );
}
As can be noted, VSLib code is significantly simpler. Moreover, it gets straight to the point: when a player is vomited on, notify everyone who got vomited. If you notice, in the VSLib code, VSLib will pass important variables (such as the victim and attacker) to you, as well as the original unmodified params table. Simplicity is very important for a productive development environment, and that's exactly what VSLib tries to promote.

Technical (and probably unimportant) side note:
The other thing you may notice is the C-style format specifier (i.e. the 's' in  %s  stands for 'string'). Using format specifiers is generally considered "easier," but that is, of course, dependent on the programmer. Reading (and even rearranging)  "%s was vomited on!"  is easier than reading/rearranging  name + " was vomited on!" . Why? If you wanted to change the text to   "A boomer vomited on   name  !"  , you can easily move the  %s . In the original, however, you'd need to concatenate extra strings like so:  "A boomer vomited on " + name + "!"  The path you choose does not usually matter in modern computers, but you may find the C-style string.format easier (and sometimes faster) than concatenating strings with the addition operator.


The above code serves to demonstrate VSLib's notifications system.
Chatbox Triggers
Chat triggers are a popular way of giving control to your players. If you have ever been on a server where you can issue a command lead by an exclamation point (e.g. !menu), then you've witnessed the power of chatbox triggers. Sometimes, user interactivity is a huge concern. "How can I allow players to issue custom commands?" Using a chatbox trigger is the answer! Using chat triggers, you can create commands that your players can fire whenever they type a certain command into the chatbox. VSLib emulates such a system via the EasyLogic.Triggers table. For example, a !helloworld command:
As you will see in the Chat Triggers chapter, creating and maintaining triggers is very easy.
The HUD system
The GUI is an important asset to your campaign or mutation. It not only conveys information, but it is also a source of interactivity. Making a dynamic, responsive HUDs is a common field of concern for graphics programmers. VSLib provides several customizable HUD objects. Custom text and values can be added anywhere one needs them (using VSLib's flexible template system). Moreover, VSLib's HUD objects employ a basic cache system to speed up rendering. Working with values of 0.0 - 1.0 may be kind of confusing, so VSLib includes a scaling system where developers can move and resize HUD items in terms of pixels.


Progress Bars

Whether you need health bars, magic bars, stamina bars, progress bars, continuous (i.e. "marquee" / looping) bars, VSLib's HUD.Bar class can render them. Creating a progress bar takes only a line of code. Moreover, the object oriented interface makes managing the HUD a lot simpler.
Selectable Mouse-navigated Menu

Often, developers want to present a set of options (a menu, perhaps) to a particular player. VSLib's HUD.Menu class can readily display a menu that is controllable by a specific player. The player can right-click to scroll through menu options and left-click to select an option. Creating a VSLib menu takes only a line of code. As with all VSLib HUD objects, the menu is completely customizable. Moreover, it is very easy to use-- each menu option can be linked directly to a function in your code.
Customizable Countdown Timer

The default timers are really cool, but sometimes they just cannot relay enough information to the end-user. VSLib includes a simple HUD.Countdown class that can relay time in a more intuitive way. Moreover, you can easily set a callback function to fire once the timer is over.
HUD.Item object

The HUD.Item class is used to create various VSLib HUD objects (such as the menu, progress bar, and timer). The class can be easily derived to incorporate your own custom menu items. Item can also be used by itself to create dynamic, customizable HUD. In most cases where the HUD is involved, the developer will normally just instantiate a HUD.Item object.
Utilities Table
Last, but not least, the utilities table includes a couple of random functions that you are likely to use throughout your projects. For example, Utils.SayToAllDel() is a function that says something with a 0.1 second delay. Now why would anyone ever want this, you may wonder. If you ever tried using Say() in InterceptChat(), you will notice that your Say() comes before the user's text, like so:
To fix this, you may find yourself using SayToAllDel() in your chatbox triggers (and custom InterceptChat functions). The result, as you have previously seen:
There are a couple of other functions-- everything from string search/replace to vector math.
Getting Started
Are you ready to give VSLib a whirl? Read the installation steps. Grab some coffee. Let's build!
Developers
I found this article helpful
I did not find this article helpful
What people are saying...
You must be logged in to post a comment.
There are no comments yet for this guide.