From SRB2 Wiki
Jump to navigation Jump to search
To do
Check if the description for SPR2_ is correct.

Freeslots are additional empty slots for Object types, states, sprites and sounds. These slots allows SOCs and Lua scripts to create completely new resources without overwriting old ones, which allows for new types of Objects to be created in addition to all the already existing ones. There are 512 freeslots for Object types and sprites, 4096 for states, and 1600 for sounds. If freeslots are not used and existing Object types are modified instead, all Objects of the modified types will change their behavior when such a SOC or Lua script is loaded, even if that might not be desirable. For example, if a pushable version of an intangible scenery Object type is created by simply making the original Object type pushable, all instances of the Object type will become pushable, even in maps where that might not desirable. Creating a copy of the Object type and, if necessary, its states in the freeslot locations prevents this issue.

Declaring freeslot names

Since v2.1, SRB2 allows declaration of custom names for freeslots, which enables use of them as named constants representing the slot number (similar to other constants like FRACUNIT, TICRATE and names for already existing Object types/states/sprites/sounds) later in the same script or in following scripts, whether SOC or Lua. The method of declaring them differs slightly between SOC and Lua:


In SOC lumps, freeslot names are declared using the Freeslot header. Anything in the block below this header will be turned into a freeslot name for a particular type of freeslot, as long the prefix of the name is one of the following:

  • MT_ – for Object type names.
  • S_ – for state names.
  • SPR_ – for sprite names. The name following this must be 4 characters long.
  • SPR2_ – for sprites that override SPR_PLAY. The name following this must be 4 characters long.
  • sfx_ – for sound names. The name following this must be 6 characters long or less. If the corresponding sound lump in a WAD or PK3 file is called DSCUSTOM, for example, then the respective sound name here should be sfx_custom.
  • TOL_ – for level types.
  • SKINCOLOR_ – for skin colors.

The newly declared freeslot name will automatically take up the next available numbered free slot for the type set. Ideally, the name following the prefix should be unique to this freeslot (and never repeated within freeslot declarations elsewhere in the script or in the rest of the WAD or PK3 file) so as to not cause any conflicts, whether with freeslots declared in other files or freeslots declared in the same file.

Example usage:


It does not matter in what order the different types of freeslot names are placed relative to each other in a freeslot block; names for Object types, states, sprites and sounds can be freely mixed together in any order. The ordering of freeslot names of the same type (e.g., states) relative to each other does not strictly matter either, but it will affect the order in which they are assigned to the freeslots and therefore how actions such as A_RandomStateRange, which depend on the ordering of the slots, interpret their values.

In SOC, it does not matter which letter case the names are declared in, as they will be converted to the correct case internally. It also does not matter where the freeslot block is placed in a SOC lump, as long as it comes before every instance of any of the declared names being used in the script.

Note that if any freeslot name has already been declared in a Lua script, it should not be re-declared in SOC as well – this just makes the game declare two freeslots with the same name, which can cause issues and wastes available freeslots. Lua scripts are always loaded before SOCs and therefore take priority over them regarding freeslots.


Lua's version of freeslot name declaration is similar to SOC's, except that it makes use of the base function freeslot() instead:


Here, all new freeslot names must be declared as strings, so quotation marks (") are needed around every individual name. The names must also be separated by commas (,) to separate each freeslot name declared. Apart from these restrictions, the choice of formatting is slightly more flexible: freeslot names can be laid out as a vertical list as shown above, or all laid out in the same line as below:

freeslot("MT_OBJECTYPE", "S_STATENAME", "SPR_SPRT", "SPR2_SPR2", "sfx_custom", "TOL_LEVELTYPE")

However, unlike in SOC, Lua is case-sensitive with names – Object type, state and sprite names are all expected to be in all-uppercase, while sound names should be in all-lowercase.

  SOC [view]
General ClearMainCfg
Objects ObjectStateSoundSprite2SpriteInfoSprite2InfoFreeslot
Unlockable content EmblemExtraEmblemUnlockableConditionSet
Miscellaneous WipesCharacterLevelCutscene / ScenePromptMenuHudItem
Related links ActionsConstantsCustom Object tutorial