Summer 2026 Music Kit Competition is now here! - Create a summer themed electronic music kit and submit it by - Enter Now!

Scripting
Intro to Lambda vScript

Lambda vScript lets you add custom behaviour to your maps by writing small JavaScript files. If you have ever chained together logic_relay, math_counter, and trigger_multiple entities and thought "there has to be an easier way to do this", this is that easier way.

Coming from Counter-Strike 2?

Lambda vScript is heavily influenced by CS2's cs_script, and many of the imports and function names are the same. It is not 1:1 compatible though, so existing CS2 scripts will need adjusting. Check the API Reference for what's available here.

You do not need to be a programmer to use it. If you can set up inputs and outputs in Hammer, you can learn enough JavaScript in an afternoon to script a map. This section of the docs is written with that in mind.

What can I do with it?

A script can do things that are painful or impossible with map logic alone:

  • Open doors, trigger effects, and fire any entity input, with conditions, counters, and randomness.
  • Show messages in chat, in the console, or in the centre of every player's screen.
  • React to gameplay: players connecting, chatting, jumping, taking damage, or getting kills.
  • React to Counter-Strike rounds: round start, round end, bomb plants, and defuses.
  • Teleport players, give weapons, change health, and make objectives glow.
  • Remember things across rounds, or even across map loads, using save data.

How it works

There are three pieces, and you already know two of them:

  1. A JavaScript file: a plain text file with a .js extension containing your script.
  2. A lambda_point_script entity: a point entity you place in Hammer. It loads your script file and acts as the bridge between the map and the script.
  3. Ordinary map I/O: your buttons and triggers send inputs to the script entity, and the script fires inputs back at your named entities.

Your script runs on the game server. It cannot access the internet, files on anyone's computer, or players' machines. It can only use the functions the game provides to it, which keeps scripting safe for everyone.

Example map

An example map is provided with Content Authoring Tools named lambda_script_zoo.vmf. It contains working examples of everything covered in these docs, including hello.js, the script used below.

Your first script

1. Create the script file

Scripts live in your game's garrysmod/scripts/vscripts/ folder. Create a new text file there called my_first_script.js and paste this in:

import { Instance } from "lambda_script/point_script";

Instance.Msg("Hello from my first script!");

That first line appears at the top of every Lambda vScript file. It gives your script access to Instance, the main scripting API. The second line prints a message to the server console.

2. Place the script entity

In Hammer, place a lambda_point_script point entity anywhere in your map and set its ScriptFile property to:

my_first_script.js

You can also write the full path, scripts/vscripts/my_first_script.js. Both work.

Can't find the entity?

Make sure you have installed the Lambda Generic FGD via Content Authoring Tools. It contains the lambda_point_script entity.

3. Run the map

Compile and load your map. You can test locally in singleplayer using the Lambda vScript Environment gamemode installed by Content Authoring Tools (see testing your scripts locally below). When the map starts, check the server console. You should see:

[lambda_script] Hello from my first script!

Congratulations, you've written a script. Everything else is just adding more lines between those two.

Making the map and script talk

The real power comes from wiring the script into your map's I/O. Here is a script that opens a door when a button is pressed:

import { Instance } from "lambda_script/point_script";

let pressCount = 0;

Instance.OnScriptInput("OpenDoor", (value) => {
	pressCount++;
	Instance.Msg(`Button pressed ${pressCount} times`);

	Instance.EntFireAtName({
		name: "security_door",
		input: "Open",
	});
});

Reading it top to bottom:

  • let pressCount = 0; creates a variable, a named value the script remembers.
  • Instance.OnScriptInput("OpenDoor", ...) tells the script: "when the map sends me an input called OpenDoor, run this code."
  • Instance.EntFireAtName(...) fires the Open input at every entity named security_door, exactly like adding an output in Hammer, but from code.

In Hammer, give your lambda_point_script a targetname (for example map_script), then add an output to your button:

OnPressed  →  map_script  →  OpenDoor

Custom inputs like OpenDoor won't appear in Hammer's dropdown, so just type the name in manually. The name must match the script exactly, including capitalisation.

Scripts can also fire the entity's own outputs (OnScriptLoaded, OnScriptError, OnScriptInput) so your map logic can continue the I/O chain. See The Script Entity for the full picture.

Setting up your editor

Lambda Content Authoring Tools provides Lambda vScript IDE, an editor built specifically for map scripting. It comes with point_script.d.ts already included, so you get autocompletion, documentation as you type, and mistake-checking for every scripting function with zero setup. It can also export your .js files directly into a map's BSP file, which handles shipping your scripts for you.

If you're new to scripting, use the vScript IDE. It is the shortest path from "empty file" to "working map".

Using another editor

You can write scripts in any text editor. If you prefer something like Visual Studio Code (free), one extra file gets you the same autocompletion and checking: copy point_script.d.ts into the same scripts/vscripts/ folder as your scripts. Then add this comment as the very first line of your script files to enable stronger checking:

// @ts-check

The declaration file is for editor tooling only. The game never runs it, and your scripts remain ordinary JavaScript.

Testing your scripts locally

Content Authoring Tools also installs a local gamemode called Lambda vScript Environment. It lets you test your scripts on a local singleplayer version of Garry's Mod, so you can iterate on your code without joining (or running) a Lambda server. Load your map there, watch the console, and use the entity's ReloadScript input to pick up changes without restarting.

Note

You may be able to use TypeScript and compile down to JavaScript, however this has not been tested and as such is not supported. There are no known community TypeScript wrappers.

Good to know

A few ground rules before you dive in:

  • Scripts are server-side. They never run on players' machines and are never sent to them.
  • No browser or Node.js features. There is no setTimeout, no fetch, no require, and no file access. For timed work the game provides its own timers, Instance.SimpleTimer and Instance.CreateTimer; see the Cookbook.
  • Scripts must be quick. Each script gets 100 milliseconds per callback before the game cuts it off. That is a lot of time for map logic; you will only hit it if something goes badly wrong, like an infinite loop.
  • Errors won't crash the server. A mistake in your script stops that script and prints the error to the server console so you can fix it.

Where to next?