-
Notifications
You must be signed in to change notification settings - Fork 8
Stripper:Source Guide (Basics)
<- (Previous) Server Installation Guide | Stripper:Source Guide - Advanced (Next) ->
- What is Stripper:Source?
- Installing Stripper:Source
- Important Information
- Stripper:Source Configuration
- Syntax
- Stripper:Source Functions
- Commands
Stripper:Source is a Metamod plugin that enables modification of map entities. This includes adding entities, removing entities, and modifying entity data.
The Stripper:Source website contains some useful references for Stripper functions. More information on Stripper:Source can be found in the readme.
Templates for Stripper:Source files can be found here. The templates contain more specific documentation on entities and techniques for working around Stripper:Source's limitations.
From this point Stripper:Source will be referred to as Stripper for conciseness.
Full installation instructions can be found in the setup guide.
Install Metamod/SourceMod as per the setup guide.
Download Stripper from here.
Extract and paste the contents of the download into the left4dead2/addons
folder.
Add -insecure
to your L4D2 launch options to run the game with Metamod/SourceMod/Stripper enabled.
Stripper modifications occur during the loading of a map. This is unlike the VScript based modifications from The Last Stand update, Valve's _commentary.txt modifications, and most SourceMod plugins, which occur after the map has loaded.
This allows for modification of certain properties that would otherwise be impossible to modify in a clean and compatible way, such as targetname
.
This also means that Stripper changes occur before the director spawns items, resulting in more correct item distributions than other methods.
Stripper cannot modify or interact with any type of object that is "baked" into the map on compile, this includes:
- Non-entity brushes
- Displacements
- Static props (prop_static)
- VRAD compiled lighting
- Internal entities, except ladders as in the L4D series they are converted to func_simpleladder
- Water
There are two main files used for Stripper, these will be in different locations depending on the installation type.
- For local servers, files are located in:
left4dead2/addons/stripper
- For competitive configs, files are located in:
cfg/stripper/[config name]
global_filters.cfg
contains Stripper code that is executed on every map, before per-map configurations.
The /maps
folder contains configurations for each individual map with Stripper modifications. The configuration file will be loaded on maps with the same name, for example a file for Dark Carnival map 2 should be named: c2m2_fairgrounds.cfg
- Stripper has a non-flexible syntax, each item MUST be declared on a seprate line.
- Each block (entity), MUST be enclosed in its own braces:
{ }
- Each property MUST be enclosed in quotes:
" "
- Properties are two quoted strings per line, separated by a space.
- The first quote is the
key
(name of the property), the second quote is the value of that key. - Each
token
(function) must be followed by a colon::
, example:add:
- Tokens do not need to be specified for each block, they will continue until another token is used.
- Whitespace (tabs, spaces, new lines) outside of a quote-enclosed property is ignored.
- However it is good practice to indent with 4-spaced tabs for readability.
- Wildcard searches (checking strings for a partial match) can be performed by using
/.*
or.*/
in place of the unknown characters, example:"model" "/.*prop_junk.*/"
- NOTE: Confirm syntax on wildcards/regular expressions.
- Comments are opened with a
;
character, and are only closed by line endings.- Multi-line/block comments are not supported.
- Prepending comments with
---
is not required, it is a historical formatting choice used by L4D2 Stripper configs.
NOTE: For the purposes of this wiki, the standard
//
comment string will be used instead of---
to correctly format the code blocks, as there is no syntax highlighting for Stripper on GitHub. Since it is within a comment, it does not affect functionality.
- Rules are read in order, future rules can override previous rules.
Stripper has 3 main functions, called tokens: add
, filter
, and modify
.
The add
function allows for the creation of new entities, the type of entity created is specified by the classname
property.
Properties of the entity can be specified and will be set upon entity creation, as long as that property is valid for the type of entity.
Any property that is not specified will be the default value for that entity type.
The classname
property MUST be specified, otherwise the game will crash with the message:
Engine Error: classname missing from entity!
.
Since we cannot interact with entities compiled into the map, a prop_static
cannot be created with add
.
To create props, alternative entity types must be used:
-
prop_dynamic
- Prop that can animate, move, or change in some way with entity inputs- This is the main replacement for static props
-
prop_dynamic_override
- For models that do not support being a dynamic prop -
prop_physics
- Props that are affected by physics, such as hittables, or movable trash cans -
prop_physics_override
- For models that do not support being a physics prop
Other more specific entities such as doors have their own prop type, see the Valve Developer Wiki for more information.
Example of using add
function:
add:
; // Create a vending machine prop
{
"classname" "prop_dynamic"
"origin" "2817 3233 -968"
"angles" "0 90 0"
"model" "models/props_office/vending_machine01.mdl"
"solid" "6"
"disableshadows" "1"
}
The filter
function removes entities from the map that match the properties specified.
Each filter block contains a list of properties that Stripper will search for matches with, if ALL of the properties in the block match with the entity's properties, it will be removed from the level.
To filter mutliple different types of entities with separate criteria, separate blocks must be created.
Removing entities that are relied upon for entity inputs and outputs will not cause a crash, but it will prevent anything depending on that entity to perform an action from doing so. However, this is often the desired result of the filter function.
Using the filter function without specifying any properties, or using an invalid syntax such as missing quotes, will cause the game to crash without an error message.
Example of using filter
function:
filter:
; // Disable the Strongman event
{
"targetname" "strongman-strongman_button"
}
{
"targetname" "strongman-strongman_adrenaline_hit_relay"
}
; // Unnamed brush the tank can hit to set off the Strongman event
{
"hammerid" "2364357"
}
; // Remove all fireaxe spawns from the map
{
"classname" "weapon_melee_spawn"
"melee_weapon" "fireaxe"
}
The modify
function is the most advanced tool Stripper provides, it directly modifies the properties of entities at run time (on map load).
Entities added or changed by Stripper CAN be searched by modify
, this allows for on-the-fly renaming of entities to modify specific entities, for example.
Execution order is very important with this kind of modification, and due to the order Stripper is loaded compared to other modifications, there can be some limitations with modifying non-compiled entities such as those added by The Last Stand update. This can be circumvented by using entity logic with a delay.
Modify has four sub-blocks:
- match - Criteria for determining which entities to modify
- replace - Replaces the value of an existing property with the value specified
- delete - Removes a property from an entity, resetting it to its default value
- insert - Adds a new property to an entity
The order these sub-blocks are specified in does not matter, they always run in the same order:
match -> replace -> delete -> insert
.
The match
function is always required, the other functions are optional.
Like with the other functions, the modify
token does not need to be specified for each modify block as long as it is not interrupted by another token.
Match functions in the same way as filter, allowing properties to be specified to search all entities on the map for a match. If all of the specified criteria of the search match an entity's properties, it will be modified by the other functions.
Wildcard searches can be used with this function.
Example of using match
function:
modify:
{
; // Find all entities with the name "cola"
match:
{
"targetname" "cola"
}
; // Insert modification sub-blocks below
}
Replace matches the specified key
name and replaces the original value of that property with the value specified in the replace
sub-block.
This is used to change the properties of the matched entities.
Example of using replace
function:
modify:
{
; // Insert match sub-block above
; // Change all spawnflags to 4
replace:
{
"spawnflags" "4"
}
}
Delete removes a property from the entity, providing that both the key
and the value
specified match a property in the entity's data.
This will reset that property to its default value. In cases where there is no "default value", such as entity I/O logic, it will simply remove the property from the entity data.
Matches MUST be exact, this includes using the correct line break character when removing I/O logic from entities.
Wildcard searches can be used with this function.
Example of using delete
function:
modify:
{
; // Insert match sub-block above
; // Remove trigger for starting director script
delete:
{
"OnTrigger" "director,BeginScript,c12m4_onslaught,1.5,-1"
}
}
Insert adds a new key or property to the entity, using the key
and value
specified
This can be used to add entity I/O logic to an entity, or to add a property that has not yet been specified in the entity data. It cannot be used to add an invalid property to the entity.
There can be some overlap between using insert
and using replace
, if a modification isn't working as expected try using the other function.
Example of using insert
function:
modify:
{
; // Insert match sub-block above
; // Add an output to enable a nav blocker
insert:
{
"OnMapSpawn" "randompath_1_navblocker,BlockNav,,0,-1"
}
}
These functions can be combined to change the properties of any entity.
Example of all modify
functions combined:
; // Take an existing entity and change it to perform the functions we want it to
modify:
{
; // Find the trigger we want to change based on its type and origin position
match:
{
"classname" "trigger_once"
"origin" "256 0 -128"
}
; // Change it to the type of trigger we want and move it to another location
replace:
{
"classname" "trigger_multiple"
"origin" "-64 30 -100"
}
; // Remove the original I/O logic that triggers when a player touches it
delete:
{
"OnTrigger" "chopper_prop,Enable,,0,-1"
"OnTrigger" "chopper_beams_template,ForceSpawn,,0,-1"
}
; // Add in the I/O logic we want the trigger to use
insert:
{
"OnEntireTeamStartTouch" "automatic_sliding_door,Open,,0,-1"
"OnEntireTeamStartTouch" "door_sound,PlaySound,,0,-1"
"OnEntireTeamStartTouch" "door_sound,StopSound,,3,-1"
}
}
Stripper adds one console command: stripper_dump
This command dumps the entity data of every entity on the map to text. This is incredibly useful as it can be searched and copied from directly, instead of trying to track down an entity in hammer, or using trial and error to find properties.
Stripper dumps provide an easy way to find the hammerid
of an entity, which is the unique ID for each entity in the map. Sometimes this can be the only way to match with a desired entity.
Alternatively, ent_dump
can be used to find entity properties, but its functionality isnt as powerful as stripper_dump
.
Dumps are located in the Stripper installation folder: left4dead2/addons/stripper/dumps
Take care when copying entity data from Stripper dumps, as the braces ({ }
) are often on the same line, which won't work if copied directly in this format.
Stripper dumps will not capture any entities that are added after Stripper loads, such as those added by _commentary.txt.