View Single Post
Author Message
thEsp
BANNED
Join Date: Aug 2017
Old 08-14-2019 , 18:13   [TUT] Creating AMXX modules (VS 2013 - 2019)
Reply With Quote #1

Hello, and welcome to this tutorial about creating AMX Mod X modules!
Althought there are many or few related tutorials, not many of them were reliable and simple.

First of all, you should have Visual Studio installed. You should also be knowing the basics of C++.

----------------------------------------------------------------------------------------------------------------------------

Initializing - creating the module
1. Open the "New project" dialog, and create a Win32 C++ project. Make sure you chose the project to be empty.
Click to show


2. Change the "Configuration type" (Right click on project > Properties) to "Dynamic Library (.dll)".
Click to show


3. We're almost set. Now create a folder named "sdk" (recommended) and put the below files into it.

4. Open "moduleconfig.h" and give credentials to your module.
Click to show

----------------------------------------------------------------------------------------------------------------------------

Programming the module
Writing beautiful code is a virtue. We'll (try to) do the exact same thing...

1. Create a header (.h) and source (.cpp) file. Both should have the same name.

2. Include the AMXX API ("amxxmodule.h"), and anything else that you need (i.e: 3rd-party libraries, MM, HLSDK etc.).
Click to show


3. A good way of keeping the module beautiful is by organizing the code well.

So create a namespace with a proper name and declare functions (+ things you need), this goes into your header.

PHP Code:
namespace ModTuto_Natives
{
    
//                     native ModTuto_PrintMsg(const Message[], any:...);
    
static cell AMX_NATIVE_CALL ModTuto_PrintMsg(AMXamxcellparams);
    
// amx = the pointer to the calling plugin, params = arguments.
    // Adding a native declaration as a comment is a good way to keep track of WHAT you ARE writing.
    
    
AMX_NATIVE_INFO ModTuto_NativesInfo[] = 
    {
        
// { "Name", Function }
        
        
"ModTuto_PrintMsg"ModTuto_PrintMsg },

        { 
NULLNULL // Add this in the end.
    
};
}; 
4. Now you have to define your functions. Make sure you have included the main header where the functions are declared.
PHP Code:
#include "modtuto.h"

void OnAmxxAttach()
{
    
MF_AddNatives(ModTuto_Natives::ModTuto_NativesInfo);
    
// Add the natives from "modtuto.h".
}

void OnAmxxDetach()
{
    
// This function is necessary, even if you have nothing to declare here. The compiler will throw a linker error otherwise.
    // This can be useful for clearing/destroying a handles system.
}

// Define the functions previously defined.
cell AMX_NATIVE_CALL ModTuto_Natives::ModTuto_PrintMsg(AMXamxcellparams)
{
    
charpFullMsg MF_FormatAmxString(amxparams10);
    
// We declared a char pointer, and gave it a value.
    // The value is, a formatted string returned from "MF_FormatAmxString", a function similar to "sprintf".
    
    
sprintf(pFullMsg"%s\n"pFullMsg);
    
// This will push '\n' (newline ANSI character) into "pFullMsg". It's recommended to use AMSTL (alliedmodders std template librarly), but we won't get too deep into it.

    
MF_PrintSrvConsole(pFullMsg);
    
// This will print "pFullMsg" in the server console.

    
return 0;
    
// What we return here goes in the calling plugin.

Bonus
1. If you keep getting an error specifying "_CRT_SECURE_NO_WARNINGS", open project properties and go to "C/C++" then "Preprocessor", and paste "_CRT_SECURE_NO_WARNINGS" in the first textbox ("Preprocessor definitions").
Click to show


2. The module (binary; ".dll" file) should have an "_amxx" suffix in order to work properly. You really don't need to name your project with it.
If renaming the module over and over again (after compiling) seems tiring, then open project properties and head to "General" settings, and append "_amxx" to the "Target Name" textbox.
Click to show

3. Make sure you don't over-include the header.
Code:
#if defined _modtuto_included // Check if module/header is already included.     #endinput // Exit. #endif #define _modtuto_included // Declare that the module/header is included.

4. Prepare the module.
Code:
#pragma reqlib modtuto // Require the module. #if !defined AMXMODX_NOAUTOLOAD // Check if current AMXX (version/build) does not automatically load modules.     #pragma loadlib modtuto // Manually load the module. #endif

5. Define the natives in your Pawn header.
Code:
native ModTuto_PrintMsg(const szMessage[], any:...);

I have uploaded the source to my GitHub account. Check its repository here.
So, in conclusion we have a fully working module.


Other references:
- AMXX SDK & misc
- Metamod & HL SDK

I've possibly done many spelling mistakes or usen incorrect terms, so correcting me is appreciated. If you got any trouble or need help (regarding the same topic) then ask me here, I'll try my best to answer.

Last edited by thEsp; 12-03-2021 at 14:48.
thEsp is offline