---
name: metamod-source
description: Riferimento operativo su Metamod:Source (MM:S), lo strato che sta fra il motore Source/Source 2 e il gioco e che ospita i plugin C++ sul server dedicato. Copre installazione e patch di gameinfo.gi / gameinfo.txt, i comandi della console `meta` (list, load, unload, info, refresh, version, game, pause...), il caricamento dei plugin via metaplugins.ini e file .vdf, le cvar mm_basedir e mm_pluginsfile, lo sviluppo di plugin con ISmmPlugin / ISmmAPI / IMetamodListener, gli hook di funzioni virtuali con SourceHook (SH_DECL_HOOK, SH_ADD_HOOK, MRES_*, RETURN_META) e la compilazione con hl2sdk e AMBuild. USA SEMPRE questa skill quando si parla di Metamod, MM:S, sourcemm, `meta list`, metaplugins.ini, file .vdf, gameinfo.gi, SourceHook, plugin che non si caricano, o quando CounterStrikeSharp e SourceMod non partono — perche' quasi sempre il problema e' nello strato Metamod sotto di loro.
---

# Metamod:Source — guida di lavoro

Verificata sui sorgenti del repo ufficiale `alliedmodders/metamod-source` (ramo di
sviluppo **2.0.0-dev**, quello che serve per Source 2 / CS2) e sulla documentazione di
<https://www.sourcemm.net> e del wiki AlliedModders. Le firme, l'elenco dei comandi e i
formati dei file sono letti dal codice, non citati a memoria.

Due rami convivono, e confonderli fa perdere tempo:

- **1.12 stabile** — i giochi Source 1 (SDK 2013, HL1DM, Black Mesa, Insurgency, ...);
- **2.0 di sviluppo** — dove sta il supporto **Source 2**, quindi CS2 e Dota 2. Per un
  server CS2 si scarica sempre la **dev build**.

## Dove guardare

| Se devi... | Leggi |
|---|---|
| installare, patchare `gameinfo.gi`, verificare che sia carico | `references/01-installazione.md` |
| usare la console: `meta list`, `load`, `unload`, `info`, `refresh` | `references/02-comandi-meta.md` |
| capire come e da dove vengono caricati i plugin (ini, vdf, alias) | `references/03-caricamento-plugin.md` |
| scrivere un plugin C++: ISmmPlugin, ISmmAPI, interfacce, build | `references/04-sviluppo-plugin.md` |
| agganciare funzioni virtuali del motore o del gioco | `references/05-sourcehook.md` |
| capire perche' non si carica qualcosa | `references/06-diagnostica.md` |

## Cos'e', in concreto

Metamod:Source **non e' un plugin del gioco**: e' uno strato che si mette *in mezzo* fra
il motore e la game DLL, intercetta le interfacce che i due si scambiano e permette a piu'
plugin C++ di agganciarsi allo stesso punto senza pestarsi i piedi. La parte che rende
possibile tutto questo si chiama **SourceHook**, ed e' una libreria per manipolare in
sicurezza le tabelle virtuali.

```
Motore Source 2  ⇄  Metamod:Source  ⇄  Game DLL (csgo)
                          │
                          ├── CounterStrikeSharp  (che a sua volta ospita plugin C#)
                          ├── SourceMod
                          └── altri plugin C++
```

La conseguenza pratica piu' importante: **CounterStrikeSharp e SourceMod sono plugin di
Metamod.** Se non partono, la prima cosa da guardare non e' il loro codice ma se Metamod
e' carico — `meta list` — perche' sotto di loro c'e' un solo strato e quasi sempre e' li'
il problema.

## Come viene caricato

Due meccanismi, che portano a due esiti visibilmente diversi in `meta version`:

| Metodo | Come | `meta version` dice |
|---|---|---|
| **GameDLL** (search path) | una riga in `gameinfo.gi` (Source 2) o `gameinfo.txt` (Source 1) | `Loaded As: GameDLL` |
| **VSP** (Valve Server Plugin) | un `metamod.vdf` nella cartella `addons` | `Loaded As: Valve Server Plugin` |

Su **Source 2 / CS2 si usa il metodo gameinfo**: in `csgo/gameinfo.gi` va aggiunta la riga

```
			Game	csgo/addons/metamod
```

e deve venire **prima** della voce `Game csgo` nella lista dei `SearchPaths` — in pratica
la si mette subito sotto `Game_LowViolence csgo_lv`. Se finisce dopo, Metamod non si carica
e `meta list` risponde `Unknown Command`.

E qui sta la trappola che si paga sempre: **`gameinfo.gi` viene sovrascritto a ogni
aggiornamento del gioco.** Dopo ogni patch di CS2 la riga va rimessa, altrimenti tutto lo
stack sopra Metamod sparisce senza un messaggio d'errore comprensibile. Vale la pena avere
uno script idempotente che lo faccia (in questo progetto: `server/setup-server.ps1`).

## I comandi che si usano davvero

```
meta list              i plugin caricati, con id, stato e versione
meta version           versione di MM:S, di SourceHook, e COME e' stato caricato
meta game              informazioni sulla game DLL e sul motore rilevato
meta info <id>         dettagli di un plugin (autore, url, licenza, data)
meta load <file|alias> carica un plugin a caldo
meta unload <id>       lo scarica
meta refresh           rilegge metaplugins.ini
```

`meta` da solo stampa il menu completo. Dalla console del **client** sono disponibili solo
`meta credits`, `meta list` e `meta version`.

## Le tre cose che spiegano quasi tutti i guai

**1. Metamod si aggiunge come *Game path*, non come cartella qualunque.** Questo ha un
effetto collaterale documentato nel codice stesso: la sua cartella diventa il percorso di
scrittura predefinito, e per esempio **il `console.log` finisce in
`csgo/addons/metamod/console.log`** invece che in `csgo/`. Non e' un bug tuo: e' l'ordine
dei search path.

**2. Un plugin nasce compilato contro una certa versione dell'API.** `GetApiVersion()`
viene confrontato con `METAMOD_PLAPI_VERSION` e con il minimo supportato: se non
combaciano il plugin viene rifiutato al caricamento. Dopo un aggiornamento di Metamod, i
plugin vanno ricompilati o riscaricati aggiornati.

**3. Gli aggiornamenti del gioco rompono lo stack, periodicamente.** Non e' prevenibile: e'
il prezzo di agganciarsi a firme e vtable di un binario che Valve cambia quando vuole.
Vedi `06-diagnostica.md` per la sequenza di ripristino.

## Rapporto con le altre skill di questo progetto

Metamod sta **sotto** CounterStrikeSharp e **sopra** il server dedicato. Quindi:

- il server, le cvar e i file `.cfg` → skill `cs2-server-dedicato`;
- il plugin C# e la sua API → skill `counterstrikesharp`;
- lo strato in mezzo, i comandi `meta`, i `.vdf` e gli hook C++ → questa.

Se stai scrivendo un plugin per CS2 e hai la scelta, **CounterStrikeSharp in C# e' quasi
sempre la strada giusta**: un plugin Metamod nativo si scrive in C++ contro l'hl2sdk, non
ha rete di sicurezza sugli errori di memoria e va ricompilato a ogni cambio di SDK. Ha
senso solo quando serve agganciare qualcosa che l'API gestita non espone.
