FAQ
Licensing, platform support, how Source2Mod relates to Metamod:Source and CounterStrikeSharp, and what to do when something does not load.
Licensing
Do I have to open-source my plugins?
No. Source2Mod is licensed under the GPLv3, but it carries an explicit MIT exception for derivative works: plugins, and any software built from the Source2Mod SDK or its headers, may be licensed under the MIT License or under any other terms you choose — including closed-source and commercial. You do not have to publish or distribute their source code.
The exception covers what you build on Source2Mod, not Source2Mod itself: Source2Mod and the SDK, and modified versions of them, stay under the GPLv3.
What else does the license say?
- A linking exception lets Source2Mod and its derivative works be linked with Counter-Strike 2, the Source 2 engine, Steam and other software running on Valve's software.
- A dual-licensing exception lets derivative works be licensed under the GPL version 2 "or any later version", for compatibility with GPLv2 code.
The authoritative text is LICENSE_INFO.txt in the source2mod repository (the SDK carries the same file), with the full GPLv3 in LICENSE.
Platforms and compatibility
Does it run on Windows?
Yes. Every release is built for Linux and Windows (source2mod_<version>-linux.tar.gz and -windows.tar.gz), and plugins build with MSVC on Windows. The differences:
- A plugin must be built separately for each platform — a
.smxis a native library. - Hot reload is Linux-only; on Windows, use
s2m unloadands2m load. - Gamedata entries need a
windowsvalue; see Gamedata.
How does it relate to Metamod:Source?
Source2Mod is a Metamod:Source plugin, so Metamod is required. Metamod loads the s2m core; the core loads your .smx plugins. Hooks go through KHook, Metamod's own detour library: Metamod, Source2Mod and every s2m plugin share one instance, so hooks from all of them coexist on the same function.
Your plugins are not Metamod plugins and do not appear in meta list — use s2m list. They can still talk to Metamod plugins: OnMetamodPluginLoad, GET_METAMOD_IFACE and OnMetamodQuery exist for that. See Plugin lifecycle.
How does it relate to CounterStrikeSharp?
They are separate, independent projects. CounterStrikeSharp is a Metamod plugin that hosts plugins written in C# on .NET. Source2Mod plugins are native C++, compiled against Source2Mod SDK, with direct access to engine memory, the schema system and KHook. Source2Mod does not need CounterStrikeSharp, and its API is its own — CounterStrikeSharp plugins do not run on it.
Porting one is mostly mechanical: Coming from CounterStrikeSharp maps the concepts one to one and ports a full plugin, and C++ for C# developers covers the language side.
Can I load Source2Mod with meta load on a running server?
No. The core refuses a late load (Late load is not supported); it has to be loaded when the server starts. Plugins, on the other hand, can be loaded and unloaded at any time with s2m load / s2m unload.
Troubleshooting
A plugin refuses to load with "KHook mismatch"
Plugin myplugin refused to load: KHook mismatch: plugin built against 1111aaaa2222, s2m core runs 3333bbbb4444 -- rebuild the plugin with the SDK's vendor/khook at the core's commit, or update the coreSource2Mod core is built against the KHook inside Metamod:Source, and every plugin against the SDK's vendor/khook. KHook's headers and its engine are one library, so a plugin built against a different KHook than the one running could corrupt hooks — KHOOK_INIT() compares the two commits and refuses the load instead. A plugin with no hooks of its own (nothing but Source2Mod's interfaces) is never checked; it does not hook, so it does not care.
- Plugin developer: update the SDK and run
python tools/deps.py update, which movesvendor/khookto the commit Metamod:Source pins, then rebuild. See SDK dependencies. - Server owner: the plugin and Source2Mod core are from different generations. Update the core to the latest release, or ask the plugin's author for a build that matches the core you run.
If a plugin was built without git metadata for KHook, the check is skipped with a note — it does not fail.
A plugin refuses to load with "plugin API version 3 but this core speaks 2"
The plugin was built against a newer SOURCE2MOD_PLAPI_VERSION than the core speaks: update the core. The other way round is fine — a plugin built against an older API loads, and the core simply never calls the callbacks it does not have. s2m version shows the API version the core expects, s2m list the one each plugin was built against.
"was built against ISource2ModMenus003, this core serves ISource2ModMenus004"
Every Source2Mod interface name carries a revision. The plugin was built against an older one: rebuild it against the current SDK. … newer than this core's …: update the core is the other direction. See Compatibility.
The server freezes for seconds and the frame report blames Source2Mod
Every plugin callback runs inside a hook of the core, so that is where the engine puts the time. Look for slow callback: … took N ms in Source2Mod log: it names the command, event, timer or menu option and the plugin. The threshold is SlowCallbackWarnMs in core.json.
A plugin does not show up at all
The core prints the reason for every plugin it could not load at start, followed by a line such as 2 plugin(s) did not load, 5 running. See the errors above. Common causes: the file is not a .smx in addons/source2mod/plugins/, it was built for the other platform, or it is missing a library it links against. If PluginAutoLoadEnabled is false in core.json, nothing loads until you run s2m refresh.
Where are the logs?
- Source2Mod messages go to the server console, tagged
Source2Mod, and toSource2Mod.login the server process's working directory. That file is recreated on every start. - Plugin messages written with
SOURCE2MOD_LOGgo to the server console, prefixed with the plugin's name. Start the server with-condebugto keep the console inconsole.log. - Crash dumps and crash reports are written to
addons/source2mod/dumps/.
The server crashed. How do I report it?
The built-in crash handler writes a minidump, symbolizes plugin frames on the next start and names the suspected module. Follow the crash handler guide, then bring the report and the dump to the Discord or open an issue on GitHub. If the suspected module is someone else's plugin, report it to its author.
My new gamedata entries are not found
Gamedata is read once, when the server starts, and the first definition of a name wins — gamedata.json is loaded before your file. Restart the server, and give your entries names the core does not already use. See Gamedata.