games / fivem
Events : TriggerEvent, RegisterNetEvent, TriggerServerEvent
Explication
Ce que vous allez apprendre
- Déclarer un event réseau avec
RegisterNetEvent - Choisir entre
TriggerServerEvent,TriggerClientEventetTriggerEventselon le besoin - Comprendre d'où vient la variable implicite
sourcecôté serveur - Cibler un joueur précis ou tous les joueurs avec
TriggerClientEvent - Enregistrer plusieurs handlers indépendants sur le même event
Dans quel contexte ?
Un joueur clique sur un bouton "Acheter" dans une boutique en jeu : ce clic doit voyager du client vers le serveur pour être traité, puis le serveur doit répondre à ce client précis (et à lui seul) pour confirmer ou refuser l'achat. Cette leçon donne le vocabulaire exact (TriggerServerEvent, TriggerClientEvent, source) pour faire circuler cette information dans les deux sens, correctement et sans ambiguïté.
Concrétiser le pont entre client et serveur
La leçon précédente a établi que client et serveur sont deux mondes séparés qui ne communiquent que par un canal dédié. Ce canal, ce sont les events : un mécanisme qui permet à un bout de code de "crier" une information (avec un nom et des données), et à un ou plusieurs autres bouts de code d'"écouter" ce cri et d'y réagir, sans que l'émetteur et le récepteur aient besoin de se connaître directement.
Trois familles d'events, trois usages différents
TriggerServerEvent part toujours d'un client et arrive sur le serveur — c'est la façon dont un joueur "annonce" quelque chose au serveur (par exemple : "je veux acheter cet objet"). TriggerClientEvent fait l'inverse : le serveur informe un client précis, ou même tous les clients à la fois. TriggerEvent, enfin, reste purement local : aucun réseau n'est impliqué, c'est juste un moyen de faire communiquer différentes parties du code au sein du même contexte (uniquement client, ou uniquement serveur).
D'où vient "source" ?
Un point qui déroute souvent les débutants : la variable source, utilisée dans un handler serveur, n'est définie nulle part explicitement — elle est fournie automatiquement par FiveM au moment où un event réseau arrive, et contient l'identifiant serveur du joueur qui a déclenché cet event. Cette variable n'a de sens QUE côté serveur et QUE dans le contexte d'un event entrant : l'utiliser ailleurs n'a aucun effet.
Ce qu'on ne peut pas envoyer
Les données transmises via un event doivent pouvoir être "sérialisées" — c'est-à-dire converties en une forme transmissible sur le réseau, comme des nombres, du texte ou des tables simples. Il est impossible d'envoyer une fonction elle-même dans un event : c'est une limite technique à connaître avant de concevoir un système plus avancé.
| Fonction | Direction | Traverse le réseau ? |
|---|---|---|
TriggerServerEvent | Client → Serveur | Oui |
TriggerClientEvent | Serveur → Client(s) | Oui |
TriggerEvent | Local (même contexte) | Non |
Piège fréquent
source n'existe et n'a de sens QUE côté serveur, dans le contexte d'un handler d'event réseau entrant. L'utiliser côté client, ou en dehors d'un handler d'event, ne référence rien de valide.
Commandes & code
Events client/serveur
Le système d'events est le seul canal de communication entre client et serveur (et entre scripts locaux).
-- SERVEUR : écoute un event déclenché par un client
RegisterNetEvent('technologik:buyItem', function(itemName, quantity)
local src = source -- 'source' est une variable globale implicite = ID de l'émetteur
print(('Joueur %s achète %dx %s'):format(src, quantity, itemName))
-- ... logique d'achat réelle (voir leçon Sécurité pour la validation)
end)-- CLIENT : déclenche l'event serveur ci-dessus
TriggerServerEvent('technologik:buyItem', 'bread', 3)-- SERVEUR -> CLIENT ciblé (un seul joueur)
TriggerClientEvent('technologik:notify', targetPlayerId, 'Vous avez reçu un message')
-- SERVEUR -> tous les clients (broadcast)
TriggerClientEvent('technologik:serverRestart', -1, 60) -- -1 = tous les joueurs connectés-- Event purement local (même contexte client OU serveur, aucun réseau impliqué)
RegisterNetEvent('technologik:localUpdate')
AddEventHandler('technologik:localUpdate', function(data)
print('Mise à jour locale reçue: ' .. tostring(data))
end)
TriggerEvent('technologik:localUpdate', { reason = 'init' })-- Plusieurs handlers peuvent écouter le même event
AddEventHandler('playerDropped', function(reason)
print(('Joueur %s déconnecté: %s'):format(source, reason))
end)
AddEventHandler('playerDropped', function(reason)
-- second handler indépendant, ex: sauvegarde des données
SavePlayerData(source)
end)Résumé
RegisterNetEventdéclare qu'un event peut être déclenché à travers le réseau.TriggerServerEvent(client → serveur) etTriggerClientEvent(serveur → client) traversent le réseau.TriggerEventreste local au contexte courant (pas de réseau).sourcen'existe que côté serveur, dans le contexte d'un event réseau entrant.- On ne peut PAS passer de fonctions dans les payloads réseau, uniquement des données sérialisables.
Exercices pratiques
Mission : l'achat qui n'arrive jamais au serveur
Objectif : Corriger un mauvais choix de fonction d'event qui empêche un achat d'atteindre le serveur, et raisonner sur les limites du système d'events.
Contexte
Un bouton "Acheter" déclenche côté client : TriggerEvent('technologik:buyItem', 'bread', 3). Le serveur a bien un RegisterNetEvent('technologik:buyItem', function(itemName, quantity) ... end), mais l'achat n'est jamais traité : aucun message d'erreur, juste un clic sans effet visible. Le joueur pense que le bouton est cassé.