Location Main > Metamod-P Extension Notes > Making a Metamod Plugin


Making a Metamod Plugin

Making a Metamod plugin requires usage of the metaAPI which was created as a wrapper around exported DLL interfaces of the GoldSRC engine and server.

If you don't start using a reference:

1) You will need the HLSDK Headers which are available in multiple places, as well as some UTIL functions from the SDK that wrap around those interfaces to do anything useful.

2) Metamod-P provides (most) of the up-to-date headers that you would need to get started making plugins included with their own sourcecode.

Useful References:
Here is a good but very sloppy/broken reference: FoxbotRef.zip
There are old plugins/src here which will require a .def file and might not run

I also made a stub plugin back when I was doing this which performs some basic functions but is updated and runs in VS2015:

+ Features

- Render HUD text to clients
- User management (storing data on each user)
- Clean coding style

- a few more things, usermsg hooks, etc.

Download mm_Stub.zip

General getting started notes (for manually starting):

// Receive engine function table from engine.
// This is the _first_ DLL routine called by the engine
C_DLLEXPORT void WINAPI GiveFnptrsToDll(enginefuncs_t* pEngfuncs, globalvars_t *pGlobals)

Note: The function GiveFnptrsToDll must be exported. If it is not exported, a badload error will occur. This was usually done by .def file, but since .def files are unnecessary and outdated for a long time now, you can simply export the function directly in MSVC using linker options of preference.

In that function, you simply grab the globalvars and engine function pointer, but you cannot hook any engine functions here or it will simply crash. These engine functions exported for calling, not for hooking.

To hook client.dll's engine functions, you must create a hook of pfnGetEngineFunctions from the meta exports and then hook in there.

C_DLLEXPORT int hGetEngineFunctions(enginefuncs_t *pEngfuncs, int *)
    pEngfuncs->pfnAllocString = HookedAllocString;
    return true;