Serveurs et administration
Héberger une partie avec ses réglages, ou un serveur dédié Linux ouvert 24 h/24 qui apparaît dans la liste des serveurs Steam, et l'administrer : groupes, permissions, exclusions et bans.
Deux façons d'héberger
| Partie hébergée | Serveur dédié | |
|---|---|---|
| Lancement | Jouer → Multijoueur → Héberger | Programme sans fenêtre sur un serveur Linux |
| Joueur local | L'hôte joue (et est superadmin) | Aucun : le serveur ne fait que servir |
| Trouver la partie | Onglet Parties (lobbies Steam), invitations, IP | Onglet Serveurs (liste Steam, favoris, réseau local), IP |
| Réglages | Réglages du serveur… dans le formulaire d'hébergement | server.cfg ou variables d'environnement |
Les deux utilisent les mêmes réglages, les mêmes groupes et les mêmes bans.
Réglages du serveur
Dans le jeu, ils sont enregistrés dans %APPDATA%\Godot\app_userdata\PhysiCore\server.cfg (bouton Dossier) ; un serveur dédié lit server.cfg à côté de son programme (créé au premier lancement, ou --config <fichier>).
| Section | Clé | Rôle |
|---|---|---|
[server] Identité | name | Nom dans la liste des serveurs |
password | Mot de passe (vide = public). Les joueurs le saisissent avant de rejoindre. | |
motd | Message d'accueil envoyé à chaque joueur | |
max_players | Joueurs max (1 à 64) | |
port | Port UDP du jeu (27015) | |
query_port | Port UDP de requête Steam (27016), pour la liste des serveurs | |
region | Région (eu, na…) | |
tags | Tags, séparés par des virgules | |
[game] Partie | gamemode | Gamemode (dédié) : sandbox, ou ws_<id> pour un gamemode du Workshop |
map | Carte (dédié) : builtin:sb_naturebox, builtin:sb_desert, builtin:sb_create ou addon:ws_<id>/maps/<fichier>.pcmap | |
map_rotation | Cartes à enchaîner | |
rotation_minutes | Minutes entre deux cartes (0 = jamais) | |
prop_limit | Props max par joueur (200 au plus) | |
npc_limit | PNJ max sur la carte, tous joueurs et scripts confondus (50 par défaut, 500 au plus) | |
pvp | Dégâts entre joueurs : désactivé, les armes du jeu ne blessent plus les autres joueurs. Les gamemodes le lisent avec game.GetServerSetting("pvp") | |
noclip | false interdit le noclip à tous, même si le gamemode l'autorise (sauf permission noclip) | |
rp_movement | Déplacements réalistes pour le roleplay (false par défaut) : démarrages et arrêts progressifs, plus lent à reculer, de côté et en montée, pas de bunny hop (pas de vitesse gagnée en sautant, peu de contrôle en l'air, un temps entre deux sauts, pas de saut accroupi plus haut), ralenti après une chute. ConVar sv_rp_movement | |
player_push | En marchant, les joueurs poussent les props non figés (avec la force d'une personne : les lourds bougent à peine) et bousculent les autres joueurs au lieu d'être bloqués (true par défaut). ConVar sv_player_push | |
force_fog | Brouillard imposé (false par défaut) : les joueurs ne peuvent plus réduire ni couper le brouillard dans Configuration → Graphismes, tout le monde voit le même (utile en PvP, ou pour l'ambiance d'un serveur RP). ConVar sv_force_fog, modifiable en direct | |
name_tag_distance | Distance en mètres jusqu'à laquelle on voit le pseudo au-dessus d'un joueur (10 par défaut, 0 = jamais) ; il s'efface en fondu sur les 2 derniers mètres, et aussi quand un mur, le décor ou un prop cache le joueur (le véhicule où il est assis ne compte pas). Les PNJ n'ont pas de nom au-dessus de la tête. ConVar sv_nametag_distance, modifiable en direct | |
[content] Contenu | workshop_collection | Identifiant d'une collection Workshop : tous ses objets sont chargés |
workshop_items | Identifiants d'objets Workshop (gamemodes, addons, maps) | |
[security] Sécurité | chat_messages | Messages de chat max par joueur toutes les 10 s |
props_per_second | Apparitions (prop ou dupe) max par seconde et par joueur | |
afk_minutes | Exclusion après N minutes sans bouger (0 = jamais) | |
require_steam | Refuse les joueurs sans compte Steam vérifié | |
anticheat | Anti-triche des déplacements (true par défaut, voir Sécurité). ConVar sv_anticheat, modifiable en direct | |
anticheat_kick | Exclut un joueur après N infractions rapprochées de l'anti-triche (6 par défaut, 0 = jamais : il est seulement remis à sa place) | |
allow_http | Autorise les requêtes web du Lua (http.Fetch, http.Post, HTTP, sound.PlayURL), côté serveur et chez les joueurs (false par défaut). ConVar sv_allow_http, modifiable en direct | |
http_whitelist | Domaines web autorisés, séparés par des virgules (sous-domaines compris ; vide = tous). Le réseau local est toujours refusé. ConVar sv_http_whitelist | |
allow_cslua | Tout joueur peut lancer du Lua sur son propre jeu avec /lua_run_cl (false par défaut : seulement avec la permission lua_run). ConVar sv_allowcslua | |
[fastdl] FastDL | enabled | Envoie le dossier fastdl/ aux joueurs (serveur dédié, voir FastDL) |
http | Téléchargement HTTP ; false = seulement par la connexion du jeu | |
http_port | Port HTTP en TCP (0 = le même numéro que le port du jeu) | |
max_rate | Débit max par joueur en Ko/s (0 = illimité) | |
max_downloads | Téléchargements HTTP en même temps, tous joueurs confondus (4 par défaut) | |
[admins] | superadmins | SteamID64 des superadmins |
Le contenu Workshop listé est téléchargé avec ses dépendances et activé pour la partie ; les joueurs le reçoivent automatiquement en rejoignant.
Serveur dédié Linux
- Dans Godot : Éditeur → Gérer les modèles d'exportation → Télécharger et installer (une seule fois).
- Dans PowerShell, à la racine du projet :
.\tools\export_linux_server.ps1. Il créebuild\linux-server\et l'archivebuild\physicore-server-linux.tar.gz(programme,start.sh,server.cfg.example). Le dossieraddons/godotsteam_servera un.gdignore: sur Windows, l'éditeur et le jeu ne chargent que GodotSteam (les deux ensemble déclarent deux foisSteamProjectSettings). Le script le retire le temps de l'export, pour que le serveur Linux aitSteamServer; ne le supprime pas. - Sur le serveur (Debian/Ubuntu) : extrais l'archive, puis
chmod +x PhysiCoreServer.x86_64 start.shet./start.sh. - Ouvre les ports UDP 27015 (jeu) et 27016 (requête Steam), et le port 27015 en TCP si tu utilises le FastDL en HTTP.
Pour la liste Steam, le serveur a besoin de la bibliothèque steamclient.so (fournie par SteamCMD) dans ~/.steam/sdk64/ :
mkdir -p ~/steamcmd ~/.steam/sdk64 && cd ~/steamcmd
curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar -xz
./steamcmd.sh +login anonymous +app_update 1007 +quit
cp linux64/steamclient.so ~/.steam/sdk64/
Sans elle, le serveur fonctionne quand même, mais seulement par IP (et sans contenu Workshop automatique).
Pterodactyl
L'egg installe le serveur depuis Steam : l'application PhysiCore Dedicated Server (App ID 5448960), téléchargée par SteamCMD en connexion anonyme (aucun compte Steam à saisir).
- Dans le panel : Admin → Nests → Import Egg, choisis
server/pterodactyl/egg-physicore.json(s'il existe déjà, importe-le par-dessus ou mets à jour l'egg, puis réinstalle les serveurs qui utilisaient l'ancien). - Crée un serveur avec cet egg (image
ghcr.io/parkervcp/steamcmd:debian), une allocation principale (port du jeu, UDP et TCP pour le FastDL) et une deuxième pour la requête Steam (Port de requête Steam). - L'installation télécharge SteamCMD puis le serveur Linux, met
steamclient.sodans.steam/sdk64/(indispensable pour la liste des serveurs Steam et le Workshop) et rendPhysiCoreServer.x86_64exécutable. - Mise à jour automatique (
AUTO_UPDATE, 1 par défaut) : SteamCMD met le serveur à jour à chaque démarrage. Branche Steam (SRCDS_BETAID) et son mot de passe (SRCDS_BETAPASS) installent une branche bêta. - Les autres variables (nom, mot de passe, gamemode, carte, collection et objets Workshop, superadmins, FastDL…) remplacent les valeurs de
server.cfg. Les objets et la collection Workshop sont téléchargés par le serveur à chaque démarrage. - Pour le FastDL, envoie tes mods dans le dossier
fastdl/avec le gestionnaire de fichiers du panel (ou en SFTP), puis redémarre.
La console du panel envoie les commandes au serveur ; le bouton Arrêter envoie quit. Les fichiers à garder entre deux mises à jour (server.cfg, convars.cfg, prop_protection.json, lua_data/, fastdl/) ne sont pas dans le dépôt Steam : SteamCMD ne les touche pas.
5448960 doit contenir le build Linux (dossier de tools\export_linux_server.ps1 : PhysiCoreServer.x86_64, PhysiCoreServer.pck, les lib*.so, start.sh…) dans un dépôt Linux publié sur la branche par défaut, et être téléchargeable en anonyme (outil serveur dédié). Si l'installation dit « PhysiCoreServer.x86_64 introuvable après SteamCMD », c'est l'un de ces deux points.PHYSICORE_<SECTION>_<CLÉ> remplace un réglage : PHYSICORE_SERVER_NAME, PHYSICORE_GAME_MAP, PHYSICORE_CONTENT_WORKSHOP_ITEMS="123,456"…FastDL : envoyer ses mods sans le Workshop
Un serveur dédié peut envoyer lui-même ses mods aux joueurs qui le rejoignent : addons (modèles, maps, véhicules, armes, playermodels, sons, Lua…) et gamemodes, sans rien publier sur le Workshop. Le Workshop ([content]) marche toujours en même temps.
- Mets chaque mod dans un sous-dossier de
fastdl/, à côté du programme du serveur (créé au premier lancement). Un dossier avec ungamemode.jsonest un gamemode, les autres sont des addons (même structure qu'un addon local). Noms de dossier : lettres, chiffres,_,-et.. - Redémarre le serveur : il prépare chaque mod (seulement ceux qui ont changé) et affiche
[FastDL] N mod(s) prêts. - Les joueurs les téléchargent en rejoignant (barre de progression sur l'écran de chargement), puis seulement quand ils changent.
PhysiCoreServer.x86_64
server.cfg
fastdl/
├── ma_ville/ addon → identifiants addon:fd_ma_ville/…
│ ├── addon.json
│ ├── maps/ville.pcmap
│ ├── models/…
│ └── lua/autorun/…
└── monrp/ gamemode (gamemode.json) → gamemode="monrp"
├── gamemode.json
├── init.lua, cl_init.lua, shared.lua
└── sound/…
Dans server.cfg, un addon FastDL se nomme fd_<dossier> (map="addon:fd_ma_ville/maps/ville.pcmap"), un gamemode par son nom de dossier (gamemode="monrp" ; il remplace un gamemode du même nom). Les fichiers préparés sont dans fastdl_build/ (régénérés tout seuls) et la clé du serveur dans fastdl.key : garde-la privée et ne la change pas, sinon les joueurs retéléchargent tout.
Téléchargement
- HTTP sur le même numéro de port que le jeu, mais en TCP (le jeu est en UDP : les deux cohabitent). Rapide, et un téléchargement coupé reprend où il en était. Sur Pterodactyl, l'allocation principale ouvre déjà le port en TCP et en UDP.
- Si le port TCP n'est pas joignable (pare-feu,
http=false), le joueur télécharge par la connexion du jeu, automatiquement. C'est plus lent, mais ça marche partout. max_ratelimite le débit de chaque joueur (HTTP et connexion du jeu) etmax_downloadsle nombre de téléchargements HTTP en même temps (les autres attendent leur tour).
Protection des mods
- Seuls les joueurs admis (version, mot de passe, bans, Steam vérifiés) reçoivent un jeton de téléchargement, valable tant qu'ils sont connectés. Sans jeton, le serveur HTTP ne donne rien, et il ne sert que les mods (aucun autre fichier du serveur).
- Le code Lua n'est jamais dans les fichiers téléchargés : les scripts client arrivent en mémoire avec les scripts du jeu, et les scripts serveur ne quittent jamais le serveur.
- Données seulement : un mod FastDL ne contient que des fichiers de données (modèles
.glb/.gltf/.fbx, images, sons, polices, maps.pcmap, JSON, texte). Les scripts, scènes et ressources Godot (.gd,.tscn,.tres,.res…) sont laissés de côté à la préparation (le serveur l'affiche) : un joueur refuse un mod qui en contient, et un mod ne peut jamais remplacer un fichier du jeu. Ainsi, rejoindre un serveur ne peut pas faire exécuter de code sur l'ordinateur du joueur. - Chez le joueur, les mods sont gardés dans un cache chiffré (AES-256, clé propre à ton serveur, donnée seulement à la connexion) aux noms illisibles : pas de dossier de modèles, de sons ou de maps à copier. Pendant la partie, ils sont lus depuis une archive qui reste chiffrée sur le disque, sans jamais être décompressés en fichiers, puis effacée en quittant le serveur. Le cache oublie les mods inutilisés depuis 30 jours.
Sécurité et anti-triche
Le serveur ne croit pas ce que les joueurs lui envoient : il vérifie lui-même. Ce qui est fait par le jeu, sans rien régler :
- Déplacements (
anticheat, activé par défaut) : chaque joueur calcule ses propres mouvements, le serveur contrôle chaque position reçue. Une vitesse impossible (téléportation, speedhack), une montée impossible, un vol (en l'air sans tomber plus de 2,5 s), le noclip là où il est interdit et le passage à travers un mur de la carte remettent le joueur à sa dernière position correcte, préviennent les admins en jeu et s'affichent dans la console ([Anti-triche] …). Aprèsanticheat_kickinfractions rapprochées (une infraction est oubliée au bout de 20 s), le joueur est exclu. Les marges sont larges : bunny hop, pentes, bousculades, lag et props qui transportent un joueur ne déclenchent rien ; les vitesses données par les scripts (ply:SetVelocity,ply:SetWalkSpeed…,/freeze) et les téléportations du serveur (ply:SetPos, réapparitions, sièges) sont prises en compte. En véhicule, la position envoyée par le conducteur est limitée à 200 m/s. - Outils et dupes : les réglages du toolgun sont bornés par le serveur (force d'un propulseur, rayon d'une roue, matériau…), il faut avoir reçu le toolgun ou le physgun pour s'en servir, et 12 actions par seconde au plus. Une dupe ne transporte que les réglages de ses gadgets, le matériau et la masse de ses props, plus ce que le Lua du serveur accepte (entités scriptées et modificateurs, recréés par leurs fonctions Lua) : impossible d'y glisser une arme ou des munitions. Ses props restent à 150 m de son origine.
- Scripts Lua : un script qui tourne plus de 5 s sans rendre la main (boucle infinie) est arrêté avec une erreur au lieu de figer le serveur ; de même chez les joueurs pour les scripts client. Les requêtes web sont coupées par défaut (
allow_http) et ne peuvent jamais viser le réseau local ; la base SQLite refuse les commandes qui ouvriraient d'autres fichiers. - Réseau : seuls les joueurs admis reçoivent les scripts client et la carte de l'éditeur ; la voix est limitée au débit d'un vrai micro.
- Pour les joueurs : les dupes et les données venant d'un serveur sont lues sans pouvoir créer d'objets ni charger de fichiers, et les mods FastDL ne contiennent que des données (voir plus haut). Rejoindre un serveur ou ouvrir une dupe du Workshop ne peut pas exécuter de code sur l'ordinateur.
Protection des props
En multijoueur, chaque prop, véhicule et PNJ appartient au joueur qui l'a fait apparaître. La protection (inspirée de FPP sur Garry's Mod) décide qui peut y toucher. Elle marche dans tous les gamemodes et le serveur vérifie chaque action : un joueur ne peut pas la contourner en trafiquant son jeu. En solo, elle ne fait rien (tout est à toi).
Tout se règle dans le menu de spawn (Q), onglet Protection. Clique dans l'onglet et le menu reste ouvert ; Q ou Échap le referme.
- Mes props (tout le monde) : pour chaque joueur, ce que tu lui permets sur tes props (physgun, toolgun, utiliser, endommager, monter dans tes véhicules). La liste est enregistrée sur ton ordinateur (
protection_buddies.json, par SteamID) et vaut dans toutes les parties. Si le serveur le permet, tu peux aussi ouvrir tes props à tout le monde pour une action. - Props des joueurs (permission
cleanup) : le nombre de props de chacun et un bouton Nettoyer. - Règles du serveur (permission
protection: l'hôte et les superadmins) : clique sur Appliquer pour envoyer les règles à tous les joueurs, y compris à ceux qui arrivent plus tard. Elles sont enregistrées dansprop_protection.json(dossier deserver.cfg) pour les parties suivantes.
| Règle | Choix | Par défaut |
|---|---|---|
| Physgun, toolgun, utiliser (E), endommager, monter dedans, pour les props, les véhicules et les PNJ des joueurs | propriétaire seul, propriétaire et amis, tout le monde | propriétaire et amis ; utiliser un prop et monter dans un véhicule : tout le monde |
| Props de la carte, par action | personne, admins, tout le monde | physgun et toolgun : admins ; le reste : tout le monde |
| Sans propriétaire (props créés par les scripts, props d'un joueur parti), par action | personne, admins, tout le monde | comme la carte |
| Admins passent outre, par action | personne, superadmins, admins | admins |
| Les joueurs peuvent ouvrir leurs props à tout le monde | oui / non | oui |
| Supprimer les props d'un joueur parti après N secondes (0 = tout de suite, ou jamais) | 0 à 3600 s, y compris ceux des admins ou non | 120 s, admins compris |
| Dire au joueur pourquoi c'est refusé | oui / non | oui |
Ce que couvre chaque action : physgun pour attraper, et R pour libérer un prop figé ; toolgun pour tous les outils du jeu et les outils Lua, le remover sur un PNJ et la sélection du duplicateur (une contrainte vérifie ses deux props) ; utiliser pour E sur un prop (bouton, entité scriptée, arme au sol) ; endommager pour les tirs, les coups et les explosions d'un joueur sur un prop, un véhicule ou un PNJ ; monter dedans pour E sur un véhicule. Si un joueur revient avant la fin du délai de nettoyage (même SteamID), il récupère ses props. Quand une action est refusée, sa raison s'affiche un moment à droite du viseur.
ProtectionCanTouch tranche avant les règles, GM.PropProtection = false désactive la protection pour un gamemode, et la bibliothèque protection avec les fonctions CPPI (ent:CPPIGetOwner(), ent:CPPICanTool(ply)…) rend compatibles les addons écrits pour les protections de Garry's Mod. Les hooks du gamemode (PhysgunPickup, CanTool, PlayerUse…) passent après la protection : ils peuvent seulement refuser en plus.Console du serveur
Dans le terminal du serveur dédié (ou la console Pterodactyl), avec tous les droits :
| Commande | Rôle |
|---|---|
help | Liste des commandes |
status | Nom, gamemode, carte, joueurs, connexion Steam |
players | Joueurs avec leur #id, SteamID, IP, groupe et ping |
say <texte> | Message à tous les joueurs |
quit | Arrête le serveur |
| commandes admin | Toutes celles ci-dessous, sans le / (ban, map, setgroup…) |
Groupes et permissions
Chaque joueur appartient à un groupe (par son SteamID). Un groupe hérite des permissions d'un autre, et a une immunité : on ne peut viser qu'un joueur d'immunité inférieure.
| Groupe | Hérite de | Immunité | Permissions ajoutées |
|---|---|---|---|
user | — | 0 | — |
moderator | user | 10 | kick, mute, freeze, goto, bring, slay, cleanup, afk_immune |
admin | moderator | 50 | ban, unban, map, gamemode, noclip, convars |
superadmin | admin | 100 | toutes (*) |
Autres permissions : setgroup, groups (créer et modifier les groupes), config (recharger la configuration), lua (recharger les scripts), protection (régler la protection des props ; superadmins seulement par défaut, /grant admin protection pour les admins), lua_run (lancer du Lua avec /lua_run, /lua_openscript et /lua_run_cl ; superadmins seulement par défaut). Un admin_groups.json créé avant l'arrivée de convars garde ses anciennes permissions : ajoute-la avec /grant admin convars. Les groupes sont modifiables en jeu (/addgroup, /grant…) et sont enregistrés dans admin_groups.json ; les joueurs dans admin_users.json, les bans dans bans.json (dans le dossier de server.cfg).
En partie hébergée, l'hôte est superadmin. Sur un serveur dédié, les SteamID de [admins] superadmins le sont ; les autres groupes se donnent avec /setgroup. Les SteamID sont vérifiés par Steam (ticket d'authentification) : impossible de se faire passer pour un admin. Un joueur n'entre qu'une fois que Steam a confirmé son identité (15 s au plus, sinon il est refusé), et un même compte ne peut pas être connecté deux fois.
steamclient.so, partie hébergée sans Steam), le SteamID annoncé par un joueur n'est pas cru : le joueur joue avec le SteamID 0. Les groupes donnés par SteamID (dont superadmins) et les bans par SteamID ne s'appliquent alors pas ; les bans par IP, si. Le serveur l'indique au premier joueur : [ServerAuth] Steam indisponible….Commandes admin
Tapées dans le chat (Y) avec un /. Un joueur se désigne par une partie de son nom, #id (voir players), son SteamID, ou ^ pour soi-même. /admin liste les commandes permises.
| Commande | Permission | Rôle |
|---|---|---|
/kick <joueur> [raison] | kick | Exclut un joueur (la raison lui est affichée) |
/ban <joueur> <durée> [raison] | ban | Bannit par SteamID et IP. Durée : 30m, 2h, 7d, 1w, 0 = définitif |
/banid <steamid> <durée> [raison] | ban | Bannit un SteamID, même hors ligne |
/banip <ip> <durée> [raison] | ban | Bannit une IP (connexions directes sans Steam) |
/unban <steamid ou ip>, /bans | unban / ban | Lève un ban ; liste les bans actifs |
/mute, /unmute <joueur> | mute | Retire / rend la parole dans le chat |
/freeze, /unfreeze <joueur> | freeze | Fige / libère un joueur |
/goto, /bring <joueur> | goto / bring | Va vers un joueur / l'amène |
/slay <joueur> | slay | Tue un joueur |
/cleanupplayer <joueur> | cleanup | Supprime ses props |
/map <carte>, /gamemode <nom> | map / gamemode | Change de carte ou de gamemode pour tout le monde |
/setgroup <joueur ou steamid> <groupe> | setgroup | Change le groupe d'un joueur |
/addgroup <nom> <hérite de> <immunité>, /delgroup | groups | Crée / supprime un groupe |
/grant, /revoke <groupe> <permission> | groups | Donne / retire une permission |
/groups | — | Liste les groupes |
/reloadconfig, /reloadlua | config / lua | Relit server.cfg et les fichiers admin ; recharge les scripts Lua |
/cvar <nom> [valeur] | convars | Lit ou change un réglage (ConVar), ex. /cvar sbox_maxprops 300 |
/cvars [filtre] | — | Liste les ConVars et leur valeur |
/lua_run <code> | lua_run | Lance une ligne de Lua sur le serveur (notée dans la console) |
/lua_openscript <fichier> | lua_run | Lance le fichier lua/<fichier> d'un addon activé (ex. /lua_openscript monaddon/test.lua) |
/lua_run_cl <code> | lua_run, ou personne si sv_allowcslua 1 | Lance une ligne de Lua sur son propre jeu (realm client) |
Réglages en jeu (ConVars)
Les gamemodes et addons déclarent leurs propres réglages (durée de manche, argent de départ…) : ce sont les ConVars. L'hôte et les joueurs qui ont la permission convars les changent en jeu par Pause → Réglages du serveur, ou avec /cvar. Des ConVars intégrées reflètent server.cfg : sbox_maxprops, sbox_maxnpcs, sbox_noclip, sbox_playershurtplayers, sv_props_per_second, sv_rp_movement, sv_player_push, sv_anticheat, sv_force_fog, sv_nametag_distance, sv_allow_http, sv_http_whitelist et sv_allowcslua. En Lua, game.ConsoleCommand("sbox_maxprops 300\n") les change comme la console du serveur.
Sur un serveur dédié, les valeurs archivées sont dans convars.cfg à côté de server.cfg, et PHYSICORE_CVAR_<NOM> impose une valeur de départ (variable à ajouter dans l'egg Pterodactyl si besoin). Les données des scripts (file.Write) sont dans lua_data/, au même endroit : pense à le sauvegarder.
En Lua
Les scripts peuvent s'appuyer sur ce système : ply:IsAdmin(), ply:IsSuperAdmin(), ply:GetUserGroup() (aussi côté client), et côté serveur ply:HasPermission(nom), ply:Kick(raison), ply:Ban(minutes, raison), ply:IPAddress(), game.GetServerSetting(clé) et game.IsDedicated().
concommand.Add("annonce", function(ply, args, texte)
if not ply:IsAdmin() then
ply:ChatPrint("Réservé aux admins.")
return
end
PrintMessage("[Annonce] " .. texte)
end)