Sprays are a type of user generated content (UGC) which allows players to "spray" an image in-game onto a surface. These images can be created by the player. As of late 2021, TF2 and L4D2 players must manually opt-in to enable sprays.
Sprays must be manually enabled using the following commands:
cl_spraydisable 0 // Don't disable sprays; enable sprays.
tf_delete_temp_files 0 // Prevent the game from deleting the cached sprays.
cl_allowdownload 1 // Allow downloads from the server, including sprays.
cl_allowupload 1 // Allow uploading files (sprays) to the server.
cl_downloadfilter all // Ensure sprays aren't filtered out of the allowed downloads.
Sprays cannot be used on a server running with sv_pure >= 1 because this disables transferring of the spray files. Sprays which a player has already downloaded and cached from elsewhere will still be visible on sv_pure >= 1 servers.
These commands can be entered into the in-game console or by adding them to autoexec.cfg. This file is located at
steamapps/common/Team Fortress 2/tf/cfg/ for TF2, and other Valve games will be in the same general location.
How to enable the developer console in TF2. The steps are similar for other Valve games.
On Linux, the file name of a spray must not contain any capital letters as it will fail to load.
The maximum file size of a spray is 512 KiB or 524,288 bytes. This limit is hard-coded into the game client and cannot be modified by server plugins.
When using a compressed (DXT) image format, it is always better to upscale a source image to the highest possible resolution for higher quality. Upscaling while using non-compressed image formats doesn't do anything useful.
A single image spray is the simplest type of spray; it consists of a single image. This also allows for using the highest possible resolution of 1024x1020 pixels with a DXT1 formatted spray.
An animated spray runs at 5 frames per second (FPS) and can have a nearly unlimited number of frames, however each frame reduces the maximum possible resolution of each of the individual frames due to the file size limit.
# FFMPEG, recommended and faster
ffmpeg -i input.webm animation/frame_%04d.png
# ImageMagick, generally slower
convert input.webm -coalesce +adjoin PNG32:animation/frame_%04d.png
These extracted frames can then be used to create an animated spray.
Sprays with mipmaps can be used to change the visible image depending on how far the player is from the spray. The downside to using mipmaps is that the spray's resolution must be a power of 2, which means the maximum resolution is 512x512 pixes. Attempting 1024x1024 pixels goes above the 512 KiB file size limit.
Mipmapped sprays can also be animated, though the file size limit can make this difficult.
It is technically possible to have an uncompressed mipmapped spray with a resolution which isn't a power of 2, but the image will likely end up skewed, have a seam, and turn into garbled nonsense at certain distances.
With anisotropic filtering enabled, the change between the mipmaps is gradual.
Without any filtering enabled, the change between the mipmaps is sharp and instantaneous.
A pixel art spray has the "point sample" flag enabled which tells the game to render the texture differently, resulting in the individual pixels being maintained without artifacting due to scaling. This flag is incompatible with mipmaps.
Pixel art images are often pre-upscaled for easier viewing and will need to be downscaled to best fit into the file size limits of sprays when using uncompressed formats.
|DXT5 (Native Resolution)
|No Point Sample
Art by Hioshiru
There are more formats than listed here which are supported with sprays, but these are the most useful ones.
DXT1, DXT1A, DXT3, and DXT5 all have the same colour quality, the only difference is the available transparency. DXT1A should generally be preferred because it allows for the highest resolution. DXT5 should be used if the source image has gradient transparency which needs to be maintained. The uncompressed formats are best used for pixel art when file size permits.
DXT1A sprays function on Linux, however the transparency will instead be opaque and black. There is no known solution to this problem. The workaround is to use DXT5.
Compressed textures must have a resolution as a multiple of 4, uncompressed textures can have any resolution. As previously mentioned, mipmapped textures will regardless require the resolution to be a power of 2.
The command for applying a spray is
impulse 201, which can be bound to the <kbd>T</kbd> key using:
bind t "impulse 201"
Sprays can be imported or changed in-game by selecting "options" and going to the "multiplayer" tab. It is highly recommended not to import any non-VTF sprays in this way because the game will otherwise autoconvert the source image into a terrible quality 256x256 pixel VTF spray. Spraymaker5000 can automatically import sprays to any game which supports them, so this step is unnecessary.
Changing a spray will only take effect when the map changes or the player reconnects to the server. The spray will not be visible to other players until it has been downloaded, which is a fairly slow process.
Using sprays in L4D2 on Linux is a hassle. The spray file must first be saved to the
materials/vgui/logos/custom/ directory. When trying to import or change a spray in L4D2 on Linux the file picker UI may appear empty, and attempting to click on directories won't work. Instead, you must type the path
materials/vgui/logos/custom/ into the "file name" field and press enter, then type the name of the spray you wish to import or change to and press enter again.