API Lua
Les fonctions globales disponibles dans les scripts des addons et des gamemodes. L'API s'inspire de Garry's Mod, en mètres. Certaines n'existent que côté serveur ou côté client (voir Lua client et réseau).
Fonctions utilitaires
print(...)
Écrit ses valeurs (autant qu'on veut, séparées par une tabulation ; nil s'écrit nil) dans la console du jeu, préfixées par [Lua].
print("Joueurs connectés :", #player.GetAll())
PrintMessage(texte)
Envoie un message système (en bleu clair) dans le chat de tous les joueurs.
PrintMessage("La partie redémarre dans 30 secondes !")
CurTime() → nombre
Temps écoulé en secondes depuis le lancement du jeu. Pratique pour mesurer une durée.
Vector(x, y, z) → Vector
Crée un vecteur 3D (en mètres, Y vers le haut). Les valeurs absentes valent 0.
| Utilisation | Résultat |
|---|---|
v.x, v.y, v.z | Lire ou modifier une composante (v.y = 10) |
a + b, a - b, v * 2 | Opérations vectorielles |
v:length() | Longueur (mètres) |
v:normalized() | Vecteur de longueur 1 |
a:distance_to(b) | Distance entre deux points |
a:dot(b), a:cross(b) | Produit scalaire, produit vectoriel |
v:Length(), a:Distance(b), v:GetNormalized(), v:Angle(), v:ToScreen()… | Noms Garry's Mod (voir Angles et vecteurs, ToScreen) |
local haut = ply:GetPos() + Vector(0, 3, 0) -- 3 mètres au-dessus du joueur
Angle(pitch, yaw, roll) → Angle
Un angle en degrés (un Vector, avec ang:Forward(), ang:Right(), ang:Up(), ang:RotateAroundAxis()). Pitch positif = vers le haut. Aides : Lerp, LerpVector, LerpAngle, math.Clamp, math.Round, math.Approach, math.Remap, math.NormalizeAngle, VectorRand, AngleRand. Voir Angles et vecteurs.
Color(r, g, b, a) → Color
Crée une couleur avec des composantes de 0 à 255 (comme GMod). a (opacité) vaut 255 par défaut.
prop:SetColor(Color(255, 120, 0)) -- orange
prop:GetColor()) a ses composantes entre 0 et 1, pas 0 et 255.Msg(...), IsValid(objet) → booléen
Msg et MsgN écrivent leurs valeurs collées les unes aux autres (sans séparateur), sur une ligne. IsValid vaut true si le joueur ou l'entité existe encore (accepte aussi nil).
SERVER, CLIENT
Booléens : on est dans un script serveur ou client.
Variables réseau globales
SetGlobalInt(nom, valeur) (serveur) et GetGlobalInt(nom, défaut) (partout), ainsi que Float, Bool, String, Vector, Angle et Entity. Les noms SetGlobal2… / GetGlobal2… désignent les mêmes variables. Voir Variables NW et NW2 et Variables réseau.
Types, conversions et erreurs
| Fonction | Rôle |
|---|---|
isfunction, isstring, isnumber, istable, isbool, isvector, isangle, IsColor, isentity / IsEntity, ispanel, ismatrix | Le type d'une valeur. Un angle étant un Vector, isvector et isangle acceptent les deux ; isentity vaut vrai pour une entité, un PNJ ou un joueur (ply:IsPlayer() pour les distinguer) ; ismatrix vaut toujours false. |
tobool(v) | false pour nil, false, 0, "0", "false" et "" ; true sinon. |
ErrorNoHalt(...), ErrorNoHaltWithStack(...) | Écrit [erreur] message dans la console sans arrêter le script (le second ajoute la pile d'appels). |
PrintTable(t) | Écrit une table et ses sous-tables, indentées et triées par clé. |
AccessorFunc(tab, champ, nom, force) | Crée tab:GetNom() et tab:SetNom(v) qui lisent et écrivent tab[champ]. force : FORCE_STRING, FORCE_NUMBER ou FORCE_BOOL convertissent la valeur ; FORCE_ANGLE, FORCE_COLOR et FORCE_VECTOR existent mais ne convertissent rien. |
baseclass.Get(nom), baseclass.Set(nom, table) | Tables de base partagées (le DEFINE_BASECLASS de GMod) : Get renvoie toujours la même table pour un nom, Set la remplit. |
local PANNEAU = {}
AccessorFunc(PANNEAU, "m_iPrix", "Prix", FORCE_NUMBER)
PANNEAU:SetPrix("50")
print(PANNEAU:GetPrix() + 1) -- 51
Aides
Texte : string.Explode(séparateur, texte, motif) (découpe ; motif = true : le séparateur est un motif Lua), string.Split(texte, séparateur), string.Implode(séparateur, liste), string.Trim(texte, caractères), string.TrimLeft, string.TrimRight, string.StartWith / StartsWith(texte, début), string.EndsWith(texte, fin), string.Left(texte, n), string.Right(texte, n), string.Replace(texte, cherché, remplacement) (sans motif), string.PatternSafe(texte) (échappe les caractères spéciaux des motifs), string.ToTable(texte) (un caractère par case).
string.FormattedTime(secondes) donne "mm:ss" ; table.Count(t), table.HasValue(t, v), table.Random(t), table.Copy(t) (copie profonde) ; unpack est le même que table.unpack. Les autres aides de Garry's Mod sont dans Bibliothèques table, math, string et bit.
Bibliothèques table, math, string et bit
Les extensions des bibliothèques standard que les addons GMod utilisent, avec les mêmes noms et le même comportement (des deux côtés).
| Bibliothèque | Fonctions |
|---|---|
table | Merge(dest, source) (récursif), Inherit(t, base) (remplit les clés absentes, t.BaseClass = base), GetKeys, IsEmpty, Empty, ClearKeys, KeyFromValue, KeysFromValue, RemoveByValue, SortByMember(t, membre, croissant), SortByKey(t, décroissant) (clés triées par valeur), Reverse, Add(dest, source), Shuffle, Flip (valeurs ↔ clés), IsSequential, GetFirstKey / GetFirstValue, GetLastKey / GetLastValue, GetWinningKey (clé de la plus grande valeur), MemberValuesFromKey, LowerKeyNames, FindNext / FindPrev (en boucle), ForceInsert, maxn, ToString(t, nom, joli), Sanitise |
math | Rand(min, max) (décimal), Truncate(n, chiffres), SnapTo(n, pas), TimeFraction(début, fin, t), AngleDifference(a, b), ApproachAngle, Dist, IsNearlyEqual(a, b, tolérance), EaseInOut, IntToBin / BinToInt, Factorial ; courbes math.ease.InSine, OutSine, InOutSine, InQuad, OutQuad, InOutQuad, InCubic, OutCubic, InOutCubic, InExpo, OutExpo, InBack, OutBack, OutElastic, InBounce, OutBounce (fraction de 0 à 1) |
string | Comma(n, séparateur) (1,234,567), NiceTime(s) (en français : "3 minutes"), NiceSize(octets) ("1.50 Ko"), ToMinutesSeconds, ToMinutesSecondsMilliseconds, ToColor("255 0 0 255"), FromColor(couleur) (texte de 0 à 255), GetExtensionFromFilename, GetFileFromFilename, GetPathFromFilename, StripExtension, SetChar, JavascriptSafe, Interpolate("{nom}", valeurs), CardinalToOrdinal ("1er", "2e"), NiceName, utf8len |
bit | Opérations sur 32 bits signés, comme LuaBitOp : tobit, band, bor, bxor, bnot, lshift, rshift, arshift, rol, ror, bswap, tohex(n, chiffres) |
print(string.Comma(1500000)) -- 1,500,000
print(string.NiceTime(7200)) -- 2 heures
print(string.Interpolate("{nom} a {n} PV", { nom = "Alex", n = 80 }))
print(bit.band(0xFF, 0x0F), bit.tohex(255, 4)) -- 15 00ff
local x = Lerp(math.ease.OutBounce(0.5), 0, 100)
util, temps et engine
| Fonction | Rôle |
|---|---|
util.Compress(texte) / util.Decompress(texte, max) | Compresse un texte (16 Mo au plus) en un texte base64, et l'inverse (nil si invalide ou plus grand que max octets). Format propre à PhysiCore : ne se lit pas avec le util.Decompress de GMod. |
util.Base64Encode(texte, sansRetours) / util.Base64Decode(texte) | Base64 (un retour à la ligne tous les 76 caractères, comme GMod, sauf si sansRetours). |
util.CRC(texte) | CRC-32, en texte (nombre positif). |
util.SHA256(texte), util.SHA1, util.MD5 | Empreintes en hexadécimal. |
util.SharedRandom(nom, min, max, graine) | Nombre « au hasard » identique sur le serveur et chez chaque joueur pour le même nom et la même graine. |
util.Stack() | Une pile : :Push(v), :Pop(n), :PopMulti(n) (table), :Top(), :Size(), :Clear(). |
util.KeyValuesToTable(texte, échappements, garderCasse) / util.TableToKeyValues(t, racine) | Format KeyValues de Valve ("clé" "valeur", blocs { }, commentaires //). Les clés sont mises en minuscules sauf si garderCasse ; les nombres sont convertis. |
util.TypeToString(v) / util.StringToType(texte, type) | Valeur ↔ texte ("1 2 3" pour un vecteur, "255 0 0 255" pour une couleur) ; type : "string", "number", "bool", "vector", "angle". |
util.IsValidPhysicsObject(ent) | Vrai si l'entité est valide et a un objet physique. |
util.AddNetworkString(nom), util.NetworkStringToID, util.NetworkIDToString | Rien à déclarer dans PhysiCore (tout nom de message net marche) : gardées pour que les scripts GMod tournent tels quels. |
FrameTime(), RealFrameTime() | Durée de la dernière image (secondes). |
RealTime(), SysTime() | Secondes depuis le lancement du jeu, avec une précision de la microseconde (pas l'horloge du serveur : voir CurTime). |
engine.TickInterval(), engine.TickCount() | Durée d'une image physique (1/60 s) ; nombre d'images physiques depuis le lancement. |
engine.ActiveGamemode() | Nom du gamemode en cours. |
include et AddCSLuaFile
include("fichier.lua") lance un autre fichier du même addon ou gamemode et renvoie ce qu'il renvoie (return … en fin de fichier). Le chemin est cherché à côté du fichier en cours, puis depuis la racine (lua/ d'un addon, le dossier d'un gamemode) ; impossible de sortir de l'addon. À appeler depuis un fichier (pas depuis la console), 32 inclusions imbriquées au plus.
Côté client, include ne trouve que les fichiers que le serveur a envoyés : les fichiers client et partagés, et ceux que le serveur a marqués avec AddCSLuaFile("fichier.lua") (sans argument : le fichier en cours). Un fichier marqué est seulement envoyé, pas lancé : c'est include qui le lance chez le joueur.
-- lua/autorun/monaddon.lua (partagé)
AddCSLuaFile("monaddon/config.lua")
local config = include("monaddon/config.lua") -- lua/monaddon/config.lua : return { prix = 50 }
print("Prix :", config.prix)
hook : événements
hook.Add(événement, identifiant, fonction)
Appelle fonction à chaque fois que l'événement se produit. L'identifiant est un nom unique (texte) : ajouter un hook avec le même événement et le même identifiant remplace le précédent. Liste des événements : Hooks.
hook.Add("PlayerDeath", "monaddon_mort", function(ply, cause)
PrintMessage(ply:Name() .. " " .. cause .. " !")
end)
hook.Remove(événement, identifiant)
Retire un hook ajouté avec hook.Add.
Le jeu sait quels événements ont au moins un hook (ou une méthode du gamemode) : certains, comme les hooks de déplacement, ne sont appelés que s'ils sont utilisés et ne coûtent rien sinon.
hook.Run(événement, ...) → valeur
Déclenche toi-même un événement (avec jusqu'à 3 arguments), y compris un événement inventé pour faire communiquer tes addons. Renvoie la première valeur non nil renvoyée par un hook.
Rechargement à chaud, débogueur et profileur
Un fichier Lua d'addon ou de gamemode enregistré pendant la partie (dans l'éditeur de code ou ailleurs) est ré-exécuté seul, sur le serveur et chez chaque joueur, sans redémarrer : variables, joueurs et entités sont gardés, les fonctions de GM, ENT et SWEP sont remplacées en place, puis le hook OnReloaded est lancé. Un hook.Add ou un timer.Create avec le même identifiant remplace l'ancien. Voir Autorefresh.
L'éditeur de code a aussi un débogueur (points d'arrêt, pas à pas, variables locales, pause sur erreur) et un profileur (temps passé par fonction et par hook).
concommand : commandes de chat
concommand.Add(nom, fonction, autoComplete, aide, flags)
Crée une commande que les joueurs tapent dans le chat : /nom arguments…. Le nom est insensible à la casse. Existe des deux côtés : une commande créée côté serveur tourne sur le serveur ; une commande créée côté client tourne sur l'ordinateur du joueur qui la tape, sans rien envoyer au serveur (elle est essayée en premier). La fonction reçoit :
| Argument | Contenu |
|---|---|
ply | Le Player qui a tapé la commande (côté client : son propre joueur) |
args | Table des mots après la commande (args[1], args[2]…) |
argStr | Tous les arguments en un seul texte |
cmd | Le nom de la commande (en minuscules) |
L'ordre de Garry's Mod, function(ply, cmd, args, argStr), marche aussi : si le deuxième paramètre de la fonction s'appelle cmd, command, com, c, name, concommand… le jeu passe les arguments dans cet ordre-là.
autoComplete(cmd, texteArgs) (facultatif) renvoie une liste de lignes complètes ("nom arg") : pour une commande client, la touche Tab dans le chat complète avec ces lignes (sans fonction, Tab complète les noms des commandes client). aide et flags sont acceptés comme dans GMod.
concommand.Add("vie", function(ply, args)
local valeur = tonumber(args[1]) or 100
ply:SetHealth(valeur)
ply:ChatPrint("Santé réglée à " .. valeur)
end)
-- En jeu : /vie 250
-- Côté client, à la façon de GMod, avec complétion par Tab.
concommand.Add("couleur_hud", function(ply, cmd, args)
print("Couleur choisie :", args[1])
end, function(cmd, texte)
return { cmd .. " rouge", cmd .. " vert", cmd .. " bleu" }
end, "Change la couleur du HUD")
concommand.Remove(nom), concommand.Run(ply, nom, args, argStr), concommand.GetTable()
Remove supprime une commande. Run lance une commande Lua de ce côté (false si elle n'existe pas). GetTable renvoie deux tables, comme GMod : les fonctions des commandes et leurs fonctions d'autocomplétion, par nom.
Commandes intégrées
| Commande | Effet |
|---|---|
/kill | Le joueur meurt (ragdoll), puis clique pour réapparaître. |
/cleanup | Supprime tous les props du joueur. |
Pour lancer du Lua à la main, les admins ont /lua_run, /lua_openscript et /lua_run_cl (voir Commandes admin). Côté serveur, game.ConsoleCommand("commande arg\n") lance des lignes comme la console du serveur (plusieurs séparées par ; ou des retours à la ligne) : say texte, une ConVar (sbox_maxprops 300), une commande admin sans le / (kick, map…) ou une commande concommand.
Côté serveur, les commandes intégrées passent avant celles des addons : un addon ne peut pas les remplacer. Une commande client du même nom serait essayée avant, chez ce joueur seulement : évite ces noms. Une commande inconnue affiche « Commande inconnue ».
player : joueurs
player.GetAll() → table
Liste (table indexée à partir de 1) de tous les joueurs présents sur la carte, sous forme d'objets Player.
for _, ply in ipairs(player.GetAll()) do
ply:ChatPrint("Coucou !")
end
player.GetByID(id) → Player ou nil
Le joueur dont l'identifiant réseau vaut id (voir ply:UserID() ; l'hôte vaut 1).
player.GetCount() → entier
Nombre de joueurs en jeu.
player.GetBySteamID(id) → Player ou nil
Le joueur dont ply:SteamID() vaut id (texte). Aussi player.GetBySteamID64.
ents : props et entités
ents.SpawnProp(modèle, position, lacet) → Prop ou nil
Fait apparaître un prop. modèle est un identifiant de prop ("builtin:crate", "addon:…" ; voir les identifiants), position un Vector, lacet une rotation autour de l'axe vertical en degrés (0 par défaut). Renvoie nil si le modèle n'existe pas.
Un prop créé par Lua appartient au « monde » : il ne compte dans la limite d'aucun joueur et ne peut pas être annulé avec la touche d'annulation.
local caisse = ents.SpawnProp("builtin:crate", Vector(0, 5, 0), 45)
if caisse then
caisse:SetColor(Color(80, 160, 255))
end
ents.GetAll() → table
Tous les props présents (objets Entity), y compris les gadgets du toolgun et les entités scriptées.
ents.FindByClass(classe) → table
Les entités d'une classe ("prop_physics" pour les props ordinaires).
ents.Create(classe) → Entity serveur
Prépare une entité scriptée ; règle-la puis appelle ent:Spawn(). Aussi ents.Create("prop_ragdoll") (un corps en ragdoll) et les classes ENT.Base = "base_nextbot" (des PNJ pilotés en Lua : RunBehaviour, loco, Path, navmesh ; voir PNJ).
Entités scriptées : ENT.Type ("anim", "point", "brush"), ENT:Think des deux côtés avec ent:NextThink, ENT:StartTouch / Touch / EndTouch avec ent:SetTrigger et ent:SetCollisionBounds, ent:SetSolid, ent:PhysicsInit, ent:SetCustomCollisionCheck (hook ShouldCollide), santé (ent:Health, SetMaxHealth), frottement et rebond, et les contraintes constraint.Winch, Hydraulic, Muscle, Motor, Pulley, AdvBallsocket. Voir Entités scriptées et Monde et physique.
Recherche
ents.FindInSphere, ents.FindInBox(min, max), ents.FindInCone(origine, direction, distance, cosAngle), ents.FindByModel(id), ents.GetByIndex(index) et ents.FindByName(nom) (entités et zones placées dans une map). Voir Chercher des entités.
protection : protection des props
Les règles de la protection des props réglées par l'hôte dans le menu de spawn. Des deux côtés (le client connaît les règles du serveur et les amis de chacun) ; c'est le serveur qui fait foi.
protection.CanTouch(ply, ent, action) → booléen
Vrai si le joueur peut faire action sur ent (prop, véhicule ou PNJ) : "physgun", "toolgun", "use", "damage" ou "enter" (monter dans un véhicule). Tient compte du hook ProtectionCanTouch, des amis, des props de la carte et des admins. Toujours vrai en solo ou si la protection est désactivée.
protection.IsEnabled() → booléen, protection.GetSettings() → table
Si la protection agit (partie en ligne, activée par le serveur, pas coupée par GM.PropProtection = false), et une copie des règles : enabled, rules[action][type] ("owner", "buddies", "everyone" ; types "prop", "vehicle", "npc"), map[action] et unowned[action] ("nobody", "admins", "everyone"), admins[action] ("nobody", "superadmins", "admins"), sharing, cleanup_delay (secondes, -1 = jamais), cleanup_admins, notify.
CPPI
L'interface commune des protections de Garry's Mod, pour les addons qui l'utilisent : CPPI.GetName(), CPPI.GetVersion(), CPPI.GetInterfaceVersion(), CPPI.GetNameFromUID(id) ; sur un prop ou un PNJ, ent:CPPIGetOwner() (le joueur, ou nil), ent:CPPICanPhysgun(ply), ent:CPPICanPickup(ply), ent:CPPICanPunt(ply), ent:CPPICanTool(ply, outil), ent:CPPICanUse(ply), ent:CPPICanDamage(ply), ent:CPPICanEnter(ply), et côté serveur ent:CPPISetOwner(ply) ; sur un joueur, ply:CPPIGetFriends() (les joueurs qu'il autorise sur ses props pour au moins une action).
-- Un outil Lua qui ne marche que sur les props qu'on a le droit de toolgun.
function TOOL:LeftClick(trace)
local ent = trace.Entity
if not IsValid(ent) or not protection.CanTouch(self:GetOwner(), ent, "toolgun") then
return false
end
-- …
end
team : équipes
team.SetUp(numéro, nom, couleur) (dans un fichier partagé), team.GetName, team.GetColor, team.Valid, team.GetAllTeams(), team.GetPlayers(n), team.NumPlayers(n), team.GetScore(n) ; côté serveur team.SetScore(n, s) et team.AddScore(n, points). Voir Équipes, points et manches.
net : messages réseau
net.Start(nom), net.Write…, puis un envoi ; l'autre côté reçoit avec net.Receive(nom, function(taille, ply) … end) et lit avec net.Read… dans le même ordre. Les noms ignorent la casse ("MonMessage" arrive à net.Receive("monmessage")) et n'ont pas besoin d'être déclarés. Guide et exemple : Messages net.
| Fonctions | Rôle |
|---|---|
WriteString, WriteInt(n, bits), WriteUInt(n, bits), WriteFloat, WriteDouble, WriteBool, WriteBit, WriteVector, WriteAngle, WriteNormal, WriteColor, WriteEntity, WriteTable | Écrire une valeur ; les Read… correspondants la relisent. WriteInt / WriteUInt bornent la valeur à ce que tiennent bits bits ; ReadBit renvoie 0 ou 1 ; WriteNormal envoie le vecteur normalisé. |
WriteData(données, longueur) / ReadData(longueur) | Octets bruts (contenu d'un fichier, texte compressé…), intacts même s'ils ne sont pas du texte valide. |
WriteType(v) / ReadType() | Une valeur avec son type : nil, nombre, texte, booléen, table, vecteur, couleur ou entité (pas un joueur : envoie-le avec WriteEntity). Constantes TYPE_NIL, TYPE_BOOL, TYPE_NUMBER, TYPE_STRING, TYPE_TABLE, TYPE_ENTITY, TYPE_VECTOR, TYPE_COLOR… |
BytesWritten(), BytesLeft() | Taille (approchée) déjà écrite / qui reste à lire : octets, puis bits en deuxième valeur. |
Abort() | Abandonne le message commencé. |
Receive(nom, nil), net.Receivers | Retire un récepteur ; net.Receivers[nom en minuscules] liste les fonctions enregistrées. |
Send(ply ou liste), Broadcast(), SendOmit(ply ou liste) serveur | À ces joueurs, à tous, à tous sauf ceux-là. |
SendPVS(pos), SendPAS(pos) serveur | Aux joueurs à moins de 250 m de pos (PhysiCore n'a pas d'ensembles de visibilité). |
SendToServer() (client) | Au serveur. |
Limites : 256 valeurs et 64 Kio par message (et par texte), 60 messages par seconde pour chaque joueur.
-- serveur : envoie un fichier de données aux joueurs à moins de 250 m d'un point
net.Start("plan")
net.WriteType(CurTime())
net.WriteData(util.Compress(file.Read("plan.json") or ""))
net.SendPVS(Vector(0, 0, 0))
-- client
net.Receive("plan", function(taille)
local quand = net.ReadType()
local plan = util.Decompress(net.ReadData())
end)
Variables NW et NW2
Sur un joueur ou une entité : ent:SetNWInt(nom, v) (serveur) et ent:GetNWInt(nom, défaut) (partout), avec les types Int, Float, Bool, String, Vector, Angle et Entity (l'entité est retrouvée à la lecture, nil si elle n'existe plus). Les noms SetNW2… / GetNW2… (et SetGlobal2… / GetGlobal2…) désignent les mêmes variables.
| Fonction | Rôle |
|---|---|
ent:SetNWVarProxy(nom, fonction) (aussi SetNW2VarProxy) | fonction(ent, nom, ancienne, nouvelle) est appelée quand la variable change, de ce côté (serveur, et chez chaque joueur à l'arrivée de la valeur). nil la retire. |
ent:GetNWVarProxy(nom) | La fonction enregistrée. |
ent:GetNWVarTable() (aussi GetNW2VarTable) | Toutes les variables de l'entité : { nom = valeur }. |
Le hook EntityNetworkedVarChanged est lancé après le proxy, pour toutes les entités.
-- client : réagir au changement de son propre rôle sans tester à chaque image
hook.Add("ClientReady", "role_proxy", function()
LocalPlayer():SetNWVarProxy("role", function(ply, nom, ancien, nouveau)
chat.AddText("Tu deviens " .. tostring(nouveau))
end)
end)
game et gamemode
game.ChangeMap(id, gamemode) (serveur) change de map et game.GetMapList() donne les maps disponibles (voir Changer de map). game.CleanUpMap() (serveur) supprime tous les props et remet ceux de la map ; game.GetMap() donne son nom ; game.GetServerSetting(clé) lit un réglage de partie du serveur ("pvp", "noclip", "prop_limit", "rotation_minutes"…) et game.IsDedicated() indique un serveur dédié. game.SinglePlayer() (serveur) est vrai dans une partie solo (lancée avec Solo, un seul joueur) et game.MaxPlayers() donne le nombre de places. gamemode.Get(nom) et gamemode.Call(fonction, ...) ; la table du gamemode en cours est GAMEMODE.
DeriveGamemode("base"), en début de ligne dans shared.lua, init.lua ou cl_init.lua, donne la base du gamemode quand gamemode.json n'a pas de champ "base" (qui reste prioritaire) : le jeu charge cette base d'abord, puis GM en hérite (GM.BaseClass). Erreur si le gamemode nommé n'est pas chargé. Voir Gamemodes.
Monde et physique
| Fonctions | Rôle |
|---|---|
util.TraceLine, util.TraceHull, util.QuickTrace, util.IsInWorld, MASK_* | Rayons et boîtes : ce qu'on touche. Voir Traces. |
ent:GetForward, ent:LocalToWorld, ent:GetPhysicsObject, ent:SetVelocity, ent:SetCollisionGroup, ent:SetParent… | Repères, physique, collisions et attaches des entités. Voir Monde et physique. |
constraint.Weld, Rope, Elastic, Axis, Ballsocket, Slider, Keepupright, NoCollide, Remove… serveur | Liens entre props, comme le toolgun. Voir Contraintes. |
util.BlastDamage(pos, rayon, dégâts, attaquant, force) serveur | Explosion. Voir Explosions. |
os.time, os.date, os.clock, os.difftime | Date et heure réelles (version sûre de os). Voir Date et heure. |
map : points, zones et entités de map
map.GetPoints(tag), map.GetPoint(nom), map.GetTriggers(tag), map.GetTrigger(nom), map.IsInTrigger(nom, pos), ents.FindByName(nom), et les hooks TriggerStartTouch, TriggerEndTouch, InitPostEntity, PostCleanupMap : lire les repères, zones et entités placés dans l'éditeur de map. Voir Points, zones et entités de map.
Dessin et messages (client)
LocalPlayer(), ScrW(), ScrH(), ScreenScale(n) / ScreenScaleH(n) (taille relative à un écran de 640 × 480), draw.*, surface.*, chat.AddText, notification.AddLegacy(texte, type, durée), notification.AddProgress(id, texte, fraction) / notification.Kill(id), gui.OpenURL(url) (le joueur confirme d'abord). Voir Dessiner le HUD, Chat en couleurs et Tableau des scores.
Rendu 3D et effets (client)
| Fonctions | Rôle |
|---|---|
vec:ToScreen() | Position d'un point du monde à l'écran |
cam.Start3D2D(pos, ang, échelle), cam.End3D2D() | Dessiner un panneau dans le monde |
Material(chemin), surface.SetMaterial, surface.DrawTexturedRect, DrawTexturedRectRotated, DrawTexturedRectUV | Images |
surface.CreateFont, SetFont, GetTextSize, SetTextPos, SetTextColor, DrawText | Polices et texte |
halo.Add | Contours autour des objets |
render.DrawLine, DrawBox, DrawWireframeBox, DrawSphere | Formes de débogage |
effects.Particles, util.Effect, util.Decal | Particules et décalcomanies |
render.ScreenFade, render.SetColorModify, render.SetBlur, DrawColorModify, DrawBloom, DrawSharpen, DrawSobel, DrawToyTown… | Effets d'écran (les Draw* dans le hook RenderScreenspaceEffects) |
render.SetMaterial, DrawBeam, StartBeam, DrawSprite, DrawQuad, DrawQuadEasy, mesh.Begin, Mesh(), stencils, surface.DrawPoly | Dessin 3D de l'image (faisceaux, sprites, maillages) |
ParticleEmitter, EFFECT (effects/), effects.Register, EffectData() | Particules et effets scriptés |
DynamicLight(id), ProjectedTexture() | Lumières dynamiques et projecteurs |
ClientsideModel(id) | Modèle visible par ce joueur seulement |
Voir Rendu 3D et effets. La caméra se remplace avec le hook CalcView ; hooks de l'image : PreRender, PostRender, RenderScreenspaceEffects.
Fenêtres et touches (client)
vgui.Create (dont DImage, DModelPanel, DColorMixer, RichText, DBinder, DTree, DHTML, DCollapsibleCategory, DCategoryList, DNumberWang, DColumnSheet, DHorizontalDivider, DGrid, DFileBrowser…), peaux Derma (derma.DefineSkin, derma.SkinHook, hook ForceDermaSkin), vgui.Register, DermaMenu, CloseDermaMenus, Derma_Message, Derma_Query, Derma_StringRequest, gui.EnableScreenClicker, input.IsKeyDown, input.IsMouseDown, input.GetKeyName, constantes KEY_* et MOUSE_* (des deux côtés). Voir Menus, clavier et souris.
Armes personnalisées
ply:Give(id) avec l'id d'une arme d'addon, weapons.GetList(), weapons.Get(id), weapons.Override(id, table) (serveur), ply:GetAmmo / SetAmmo / GiveAmmo / RemoveAllAmmo / GetClip, et les hooks PlayerFireWeapon, PlayerReload, WeaponExplosion. Voir Armes personnalisées.
Armes et outils en Lua
Armes en Lua (fichiers weapons/, table SWEP, weapons.Register, weapons.GetStored, weapons.IsLua), outils de toolgun (fichiers stools/, table TOOL, tool.Register, tool.Get, tool.GetList), armes au sol (ply:DropWeapon, ply:SelectWeapon, ply:GetWeapon) et hooks CanTool, PlayerUse, PlayerSwitchWeapon, PlayerCanPickupWeapon. Modèles de vue : SWEP.ViewModel, SWEP.UseHands, SWEP.ViewModelFlip, SWEP:GetViewModelPosition, SWEP:CalcViewModelView, SWEP:PreDrawViewModel, SWEP:DrawWorldModel et les hooks CalcViewModelView, PreDrawViewModel, PostDrawViewModel (client). Tirs : SWEP:FireBullets passe par le hook EntityFireBullets. Voir Armes et outils en Lua.
Bac à sable : annulation, nettoyage, dupes, menus
| Fonctions | Rôle |
|---|---|
undo.Create, undo.AddEntity, undo.AddFunction, undo.SetPlayer, undo.SetCustomUndoText, undo.Finish, undo.GetTable serveur | Entrées de la touche Annuler. Voir Annulation. |
cleanup.Register, cleanup.GetList, cleanup.Add, cleanup.ReplaceEntity, cleanup.CC_Cleanup, cleanup.CC_AdminCleanup | Catégories de l'onglet Nettoyage. Voir Nettoyage. |
duplicator.RegisterEntityClass, RegisterEntityModifier, StoreEntityModifier, ClearEntityModifier, Copy, Paste, CreateEntityFromTable, FindEntityClass serveur | Entités scriptées et données dans les dupes. Voir Dupes. |
list.Set, list.Add, list.Get, list.GetForEdit, list.HasEntry, list.Contains, list.GetTable | Listes nommées ("SpawnableEntities"). Voir Listes. |
properties.Add, properties.CanBeTargeted, properties.List, properties.GetHovered (client) | Actions du menu contextuel (N). Voir Menu contextuel. |
spawnmenu.AddCreationTab, AddToolTab, AddToolCategory, AddToolMenuOption, GetToolMenu, GetTools, GetCreationTabs (client) | Onglets du menu de spawn et panneaux d'options (DForm). Voir Menu de spawn. |
Hooks StartCommand, CreateMove, SetupMove, Move, FinishMove (client), ply:SetMoveType (serveur), ply:GetMoveType, MOVETYPE_* | Déplacement du joueur (CMoveData, CUserCmd ; cmd:GetMouseX() / GetMouseY() : mouvement de la souris en pixels depuis la commande précédente, côté client seulement, 0 sur le serveur). Voir Déplacement du joueur. |
Entités du menu de spawn : ENT.Spawnable, ENT.AdminOnly, ENT:SpawnFunction ; voir Entités scriptées.
Os, données, web et rendu
| Fonctions | Rôle |
|---|---|
ent:LookupBone, GetBonePosition, GetBoneMatrix, ManipulateBone*, SetupBones / InvalidateBoneCache (recalcule la pose tout de suite : GetBonePosition à jour après un ManipulateBone*), GetAttachment, SetSequence, SetCycle, SetSubMaterial, SetRenderMode, Ignite, Dissolve, util.ScreenShake | Os, animations et effets des props, joueurs et PNJ. Voir Os, animations et effets. |
ENT:SetupDataTables / NetworkVar, ENT:Draw / ent:DrawModel, ENT:UpdateTransmitState, ents.CreateClientProp, SafeRemoveEntity | Voir Entités scriptées. |
sql.Query, QueryRow, QueryValue, SQLStr…, ply:GetPData / SetPData | Base SQLite et données par joueur. Voir Base de données. |
http.Fetch, http.Post, HTTP, sound.PlayURL (client) | Requêtes web (désactivées par défaut). Voir Requêtes web. |
CreateMaterial, GetRenderTarget, render.PushRenderTarget, render.RenderView (client), util.Decal(nom, début, fin) | Matériaux, caméras et décalcomanies. Voir Rendu 3D et effets. |
language.Add, language.GetPhrase (client) | Traductions, "#clé" dans les fenêtres. Voir Traductions. |
player_manager.RegisterClass, SetPlayerClass, RunClass… | Classes de joueur. Voir Gamemodes. |
drive.PlayerStartDriving, drive.Register… | Piloter une entité. Voir Piloter une entité. |
Véhicules
ents.CreateVehicle(id, position, angle) (serveur), veh:GetDriver(), veh:GetSpeed(), veh:SetThrottle(), ply:EnterVehicle()… et les hooks CanPlayerEnterVehicle, PlayerEnteredVehicle, PlayerLeaveVehicle. Voir Véhicules.
Sons, lumières et traces
ent:EmitSound, sound.Play, CreateSound, sons scriptés (sound.Add{ name = "Arme.Tir", sound = {…}, level, pitch, volume }, sound.GetTable, sound.GetProperties : le nom s'utilise partout à la place d'un fichier), surface.PlaySound et sound.PlayFile(chemin, drapeaux, fonction(canal, code, erreur)) (client), hook EntityEmitSound, ents.CreateClientLight (client), ents.FindInSphere, ply:GetEyeTrace, ply:EyePos, ply:GetAimVector. Voir Sons et lumières.
Soleil, ciel et brouillard
env.SetSunAngle, env.SetSunColor, env.SetSunBrightness, env.SetSkyColor, env.SetSkyTime, env.SetTimeScale, env.SetAmbient, env.SetFog, env.SetSkyTexture(chemin, rotation) (ciel panoramique d'un dossier materials/skybox/) et leurs env.Get…. Serveur : tous les joueurs ; client : effet local. Voir Soleil, ciel et brouillard.
Préchargement des modèles (client)
util.GetModelList(), util.PrecacheModel(id, fonction), util.IsModelPrecached(id) et le hook ClientReady : charger les modèles 3D en avance pour éviter les freezes. Voir Précharger les modèles.
killicon : fil des éliminations (client)
Le jeu affiche les morts en haut à droite (6 lignes, 6 secondes) : tueur [icône] victime, aux couleurs des équipes. L'icône est celle de la classe de l'arme en main du tueur, sinon de la cause : fall, explosion, burn, crush, drown, suicide, generic (icônes en texte par défaut). Une classe sans icône s'affiche [classe].
| Fonction | Rôle |
|---|---|
killicon.Add(classe, matériau, couleur) | Une image (chemin comme Material()). |
killicon.AddFont(classe, police, symbole, couleur), AddTexCode (même chose) | Un texte ou symbole dans une police. |
killicon.AddAlias(classe, autre) | Utilise l'icône d'une autre classe. |
killicon.Exists(classe), Get(classe), GetSize(classe) → l, h | Lire les icônes. |
killicon.Draw(x, y, classe, alpha) | Dessine l'icône centrée sur x (haut à y), dans HUDPaint. |
Hooks AddDeathNotice et DrawDeathNotice pour remplacer ou cacher le fil. L'annonce dans le chat (PlayerDeathNotice) reste.
killicon.Add("arme_laser", "monaddon/killicons/laser.png", Color(255, 80, 80)) -- chemin comme Material()
killicon.AddAlias("arme_laser_lourd", "arme_laser")
steamworks et achievements (client)
Steam vu du joueur ; sans Steam lancé, les fonctions ne font rien (false, "", rappel avec nil). Les identifiants Workshop et SteamID64 sont des textes.
| Fonction | Rôle |
|---|---|
steamworks.IsSteamAvailable() | Steam est-il lancé. |
steamworks.IsSubscribed(id), steamworks.ShouldMountAddon(id) | Le joueur est abonné à cet élément ; l'addon est activé. |
steamworks.ViewFile(id) | Ouvre la page Workshop dans l'overlay Steam. |
steamworks.FileInfo(id, fonction(info)) | info = { id, title, description, owner, created, updated, size, tags, up, down, installed }, ou nil. |
steamworks.DownloadUGC(id, fonction(dossier)) | Télécharge l'élément (sans abonnement ni activation) ; dossier = son dossier d'installation, ou nil. |
steamworks.GetPlayerName(steamid64), steamworks.RequestPlayerInfo(steamid64, fonction(nom)) | Nom Steam d'un joueur (la demande répond au bout d'environ 1 s). |
achievements.Count(), GetName(i), GetDesc(i), IsAchieved(i), GetCount(i), GetGoal(i) | Les succès Steam de PhysiCore, en lecture seule (i à partir de 0). Les compteurs de GMod (achievements.SpawnedProp()…) existent mais ne font rien. |
file, util et ConVars
file.Write, file.Read, file.Append, file.Exists, file.Delete, file.Find (deux tables : fichiers, dossiers), file.Open (lecture et écriture binaires), file.AsyncRead… (dans le dossier de données du gamemode ou de l'addon), util.TableToJSON, util.JSONToTable, CreateConVar, GetConVar, CreateClientConVar, cvars.AddChangeCallback, RunConsoleCommand. Voir Données et réglages.
timer : minuteries
timer.Simple(délai, fonction)
Appelle fonction une seule fois après délai secondes.
timer.Create(identifiant, délai, répétitions, fonction)
Appelle fonction toutes les délai secondes, répétitions fois (0 = à l'infini). Un identifiant déjà utilisé remplace l'ancienne minuterie.
timer.Remove(identifiant)
Arrête une minuterie créée avec timer.Create.
timer.Exists(identifiant), timer.TimeLeft(identifiant), timer.RepsLeft(identifiant)
La minuterie existe-t-elle ; secondes avant son prochain appel ; répétitions restantes (0 = à l'infini).
timer.Adjust(identifiant, délai, répétitions, fonction)
Change le délai, les répétitions ou la fonction d'une minuterie (nil = inchangé). Renvoie false si elle n'existe pas.
timer.Pause, timer.UnPause, timer.Toggle, timer.Stop, timer.Start
Met en pause / reprend / bascule une minuterie (le temps restant est gardé). Stop la met en pause et remet son compte à rebours au délai complet ; Start la relance, elle aussi pour un délai complet. Toutes renvoient false si la minuterie n'existe pas.
-- Fait pleuvoir des balles toutes les 2 secondes, 10 fois.
timer.Create("pluie", 2, 10, function()
local x = math.random(-10, 10)
local z = math.random(-10, 10)
ents.SpawnProp("builtin:ball", Vector(x, 15, z))
end)
Bac à sable et sécurité
Les scripts tournent dans un environnement isolé, pour qu'un addon téléchargé ne puisse pas nuire aux joueurs.
| Disponible | Indisponible |
|---|---|
Fonctions de base (pairs, ipairs, tostring, tonumber, pcall, type, load pour du texte…), bibliothèques string, math, table, coroutine, utf8, debug.traceback (le seul élément de debug), include, types mathématiques de Godot (Vector3, Array, Dictionary…) | io, os (sauf os.time, os.date, os.clock et os.difftime), require, dofile, loadfile, string.dump, load de code binaire, le reste de debug, et toute classe du moteur (nœuds, fichiers, réseau…) |
Les seuls fichiers accessibles sont ceux du dossier de données du gamemode ou de l'addon, avec file.* (voir Données et réglages). Chaque fichier Lua tourne dans son propre environnement : ses variables globales vont dans _G comme d'habitude, mais file y désigne le dossier de son propriétaire.
Erreurs et pile d'appels
Une erreur dans un script ou dans un hook est interceptée : elle s'affiche dans le chat ([Lua] Erreur : …, ou [Lua client]) et dans la console de l'éditeur de code, sans arrêter le jeu ni les autres hooks. Les scripts client suivent les mêmes règles.
Le message est suivi de la pile d'appels (pile d'appels :, puis une ligne fichier:ligne: in … par fonction appelée), pour voir d'où vient l'erreur ; les lignes internes du jeu sont retirées. Dans ton propre code, xpcall(fonction, debug.traceback) et ErrorNoHaltWithStack donnent la même information.
local ok, err = xpcall(function() return nil + 1 end, debug.traceback)
if not ok then print(err) end -- le message, puis « stack traceback: » et les lignes
Un script qui tourne plus de 5 secondes sans rendre la main (boucle infinie, calcul sans fin) est arrêté avec l'erreur script arrêté : il tournait depuis plus de 5 s…, au lieu de figer le serveur ou le jeu du joueur. Pour un long travail, découpe-le avec timer.Simple ou un Think qui en fait un peu à chaque image. La limite vaut aussi dans les coroutines (coroutine.create, coroutine.wrap).