Getting Started (for Server Operators) - nosoop/SM-TFCustomWeaponsX GitHub Wiki

First Run

The installation comes with a sample config in configs/cwx/example_items.txt, with one primary weapon each for Pyro and Demoman as a demonstration.

Once the plugin has been loaded in, switch to Pyro, open the chat and type /cwx. In the menu that pops up, select the "Primary weapon" option, and then "The Airblaster". You will have the weapon the next time you touch the resupply locker or respawn; you will be respawned immediately only if you are in spawn, not in sudden death, and you've set your game to automatically respawn on loadout changes using the tf_respawn_on_loadoutchanges ConVar.

Switch to Demoman, then select "The 'Grenade Launcher' Launcher".

To unequip the weapons, open up the menu again on Pyro / Demoman and select "[No custom item]".

Creating a new item from scratch

New items can be added by adding a new text file within configs/cwx/. There is no particular naming scheme to adhere to (as of rr-42, these files can be placed within subdirectories as well — files in subdirectories named "disabled" will not be processed). Multiple items can be added to one file, making it easy to organize them in groups.

A minimal weapon configuration is as follows:

"Items"
{
	"{my weapon id}"
	{
		"name"			"My Custom Item"
		"inherits"		"item_to_inherit_from"
		// other key / value entries for the item...
	}
	"{another weapon}"
	{
		// ...
	}
}

"{my weapon id}" can be any unique identifier you want (with a limit of 63 characters), but it must not change once you've assigned it[^1]. It's used internally to determine which items a player has equipped. Ideas for unique identifiers include:

  • A UUID, such as {3e8975f2-b1ad-40ef-b6f7-33a7a69a7df7}
  • A name using reverse domain name notation, such as com.github.me.MyFairAndBalancedWeapon
  • Your credit card number plus the three wacky digits on the back

This is not displayed to players on the server, but may be used in admin commands. (It does not have to be in {curly braces}.)

ℹ️ If you end up with duplicate identifiers, CWX will log a message indicating which files contain duplicates on startup, and will ignore the items specified past the first.

Comments are denoted by two forward slashes // and continue to the end of the line. Multiline comments /* ... */ are not supported at this time (CWX currently uses the game's KeyValues parser internally; maybe someday it'll be switched to SMC).

Here are the supported key / value entries:

  • name defines the item name. This is displayed to players.
  • localized_name is an optional subsection containing a mapping of language shortcodes to localized item names.
    • The available shortcodes are defined in SourceMod's configs/languages.cfg file.
    • These override the displayed name for players based on their game's language setting. If no localized_name subkey exists for an item, name will be displayed instead.
    • ⚠️ When localizing names, keep in mind that radio menus have a 512-byte budget, and some of that is consumed for rendering menus correctly. Non-ASCII characters consume multiple bytes as well.
  • inherits is a special key. It takes a name from the game item schema (items_game.txt), and determines the item definition index, class name, and class loadout slots. So, if you wanted to create something based on the Shortstop, you can set the value to The Shortstop; if you want a multi-class Shotgun, you can set it to Upgradeable TF_WEAPON_SHOTGUN_PRIMARY. And so on.
    • This is not required; you can instead manually specify or override those properties through the defindex, item_class, and used_by_classes keys described below.
    • For reference, a complete list of items is available here. Names should be taken from the "Internal Name" column for use in the configuration file.
  • defindex specifies the item definition index that the item should use.
  • item_class specifies the entity class.
    • Unlike CW3, the full classname must be provided (that is, you need tf_weapon_flamethrower instead of flamethrower).
    • CWX translates multiclass item classnames on item creation time, so you can use tf_weapon_shotgun and it'll be translated correctly for player classes that can normally equip it.
      • ⚠️ For player classes that can't, you'll have to specify the modified classname directly (e.g. tf_weapon_shotgun_soldier when wanting to apply a secondary loadout slot Shotgun on Sniper, or something). Or patch the game's TranslateWeaponEntForClass function, but that's beyond the scope of this exercise.
  • used_by_classes is a subsection containing class names and the corresponding loadout slot that the item can be used in; this can be used to apply items on classes that don't normally support it.
    • ⚠️ This must match the loadout slot that the game would normally put the item in; you can't assign a primary slot item to a non-primary slot in this way. Except for the Revolver (which is a secondary-slot item on the Spy), because that's just an extremely weird edge case.
    • ⚠️ Items can still be picked up by the class they were originally intended for, even if you specify otherwise here.
    • 🧪 Unstable: As of rr-53, cosmetics may possibly be placed into any normal loadout slot. While validity checks should pass when it comes to persistence, the item will retain the original loadout slot otherwise.
      • e.g.: Using CWX, a Sniper can have a Razorback-like wearable as a primary item and an SMG as a secondary, but the game and other plugins will treat it as if the Sniper had two items in their secondary slot. This is likely to result in unintended plugin behavior.
  • keep_static_attrs determines whether or not existing static attributes are preserved on an item. This is enabled by default.
    • ⚠️ If this is disabled, minmode viewmodels will not work.
    • ⚠️ Flamethrowers all have some default static attributes that, if this option is disabled, need to be applied for particle effects to render as they normally would.
  • attributes_game is a subsection for native game attributes. Key / value pairs specify attribute names and values, respectively. Server-side string attributes like custom projectile model work as intended.
    • For reference, a complete list of attributes declared in the schema is available here.
    • ⚠️ If you plan on making custom weapons available in MvM, take care to use attributes that do not match any MvM upgrades, or inject new attributes so they don't overlap. See issue #42 for additional details.
    • ⚠️ You cannot apply string (and other non-primitive) attributes that are read on the client side using this. Your game client will very likely crash.
  • attributes_custom is a subsection for Custom Attribute framework attributes. Follows mostly the same structure as attributes_game, but can be extended in certain ways.
  • access is a SourceMod "command string" that can be used to determine whether or not a player is allowed to equip an item. This can be used to restrict access of the item (or sets of items that share the same command string) to a certain group of people (such as testers or admins).

To load your weapon configuration and equip your item, reload the plugin by running sm plugins reload cwx.

ℹ️ If you don't see your item(s), check your server console output and error logs; CWX will output a message explaining most failures (unless your config is straight-up malformed).

[^1]: You technically can, but you'd need to ensure no players are using it, or you'd need to manually erase the references to the old name in the inventory backend. This will not be done for you automatically.

Extended Data

With X.0.8-72aadbf (rr-50), a new extdata section was added. This section is intended to have nested (but otherwise free-form) subsections for other plugins to retrieve and work with. For these, you will need to refer to the documentation of any plugins using this functionality.