Eigenes Modul
Ein eigenes Modul ist eine normale FiveM-Ressource, die das SDK nutzt und sich beim Core anmeldet. Du brauchst dafür keinen Zugriff auf fremden Modulcode.
Aufbau
resources/mein_modul/
├── module.config.mjs # einzige Quelle der Wahrheit
├── src/
│ ├── server/index.ts
│ ├── client/index.ts
│ └── shared/config.ts
├── locales/
│ ├── de.json
│ └── en.json
├── sql/
│ └── 001_init.sql
└── nui/ # optional, nur mit Oberfläche
module.config.mjs
Diese Datei beschreibt das Modul. Die fxmanifest.lua wird daraus generiert —
bearbeite sie nicht von Hand, dein Eingriff wäre beim nächsten Build weg.
export default {
name: 'mein_modul',
version: '0.1.0',
description: 'Was das Modul tut',
dependencies: ['5mc_core'],
sql: ['sql/001_init.sql'],
nui: {
page: 'dist/nui/index.html',
files: ['dist/nui/index.html', 'dist/nui/**/*'],
},
};
Das Feld sql meldet deine Migrationen beim Core an. Sie laufen automatisch beim
Start, auch wenn dein Modul vor dem Core hochkommt.
Server-Einstieg
import { onNet, emitClient, log } from '@5mc/sdk';
import { query } from '@5mc/sdk/db';
import { z } from 'zod';
const core = exports['5mc_core'];
onNet(
'meinmodul:kaufen',
z.object({ id: z.string().min(1).max(64) }),
async (source, { id }) => {
const char = core.getCharacter(source);
if (!char) return;
// Entscheidungen gehören auf den Server. Der Client sagt, was er will,
// nicht was das Ergebnis ist.
const preis = await preisFuer(id);
if (!core.removeMoney(source, 'cash', preis)) {
emitClient('meinmodul:fehler', source, { grund: 'zuwenig' });
return;
}
log.info(`${char.id} kauft ${id}`);
},
);
Client-Einstieg
import { onClient, emitServer, callback } from '@5mc/sdk';
// Mit Oberfläche: einmal aufrufen, dann kennen NUI-Seiten Marke und Sprache
import { installNuiEnv } from '@5mc/sdk';
installNuiEnv();
onClient('meinmodul:fehler', ({ grund }) => {
// ...
});
Bauen und starten
node tools/build-resource.mjs resources/mein_modul
Dann in die server.cfg eintragen — nach 5mc_core — und neu starten.
Während der Entwicklung baut ein Watch-Modus bei jeder Änderung neu:
pnpm dev
Der Neustart im Server passiert dabei nicht automatisch. Mit der Dev-Brücke (nur im Entwicklungsbetrieb) geht das von außen:
node tools/serverctl.mjs restart mein_modul
Vier Regeln, die Ärger sparen
- Der Server entscheidet. Der Client meldet Absichten. Preise, Bestände und Rechte prüfst du serverseitig, immer.
- Jedes Event bekommt ein Schema. Ohne Schema nimmt das SDK es nicht an.
- Keine Dauerschleifen. Arbeite mit Events und Zuständen. Ein
while (true)mit kurzem Warten frisst Leistung auf jedem Client. - Texte in die Sprachdateien. Auch deine eigenen. Sonst kann dein Modul nicht mit umgestellt werden, wenn der Server auf Englisch läuft.
