Module 03 · Leçon 4 sur 6
Les tables : listes et dictionnaires
Comprends les tables de Luau (listes et dictionnaires), lis les boucles qui les parcourent, et vérifie les scripts qui gèrent toutes les pièces et kill bricks de ton obby.
- ⏱️ 40 min
- 📝 Quiz de 7 questions
- 🔄 Vérifié le 24 octobre 2026
Sur cette page
- Qu’est-ce qu’une table ?
- Les tableaux
- Lire et modifier un élément
- Ajouter, retirer, chercher
- Parcourir une table
- L’itération générale : for ... in
- ipairs, pairs et la boucle numérique
- Les dictionnaires
- Les tables imbriquées
- Copie ou même table ? Les références
- Les objets Roblox renvoient aussi des tables
- Fil rouge : un seul script pour toutes les kill bricks
- Fil rouge : toutes les pièces qui tournent
- Tableau ou dictionnaire : comment choisir ?
- Lire ce code comme un relecteur
- Exercice 1 : que va afficher l’Output ?
- Exercice 2 : ce code fait-il ce qu’il annonce ?
- Quiz de fin de leçon
🎯 Dans cette leçon, tu vas apprendre à…
- Lire et modifier des tableaux (listes) et prévoir le résultat d’un parcours
- Reconnaître dictionnaires clé/valeur et tables imbriquées, et choisir la bonne structure
- Comprendre qu’une table est partagée par référence, et savoir la copier
- Vérifier un script qui gère tout un dossier de Parts
Jusqu’ici, chaque variable contenait une seule valeur. Mais un jeu manipule des collections : la liste des joueurs, les étapes d’un niveau, les objets de la boutique… En Luau, un seul outil sert à tout ça : la table. C’est la structure de données la plus importante du langage, et tu en verras dans presque chaque script produit par une IA : savoir les lire est indispensable. À la fin de cette leçon, un seul script gérera toutes les kill bricks et toutes les pièces de l’Obby des Nuages.
Qu’est-ce qu’une table ?
Une table est un conteneur qui range plusieurs valeurs. On la crée avec des accolades. Elle peut servir de deux façons :
- comme tableau (ou liste) : des valeurs rangées dans l’ordre et numérotées 1, 2, 3… ;
- comme dictionnaire : des valeurs rangées sous un nom (une clé).
local vide = {} -- une table vide
local etapes = {"Décollage", "Nuages", "Sommet"} -- un tableau
local joueur = {pseudo = "Lea", etape = 3} -- un dictionnaire
Les tableaux
Lire et modifier un élément
Chaque élément d’un tableau a un indice (sa position). En Luau, le premier indice est 1 (et non 0 comme dans beaucoup d’autres langages).
local etapes = {"Décollage", "Nuages", "Tempête", "Sommet"}
print(etapes[1]) --> Décollage
print(etapes[4]) --> Sommet
print(etapes[5]) --> nil (il n'y a pas de 5e élément)
print(#etapes) --> 4 (le # donne la longueur du tableau)
etapes[2] = "Mer de nuages" -- on remplace le 2e élément
print(etapes[2]) --> Mer de nuages
Garde tes tableaux sans trous : si tu mets nil au milieu d’un tableau (etapes[2] = nil), # peut renvoyer une longueur inattendue et certaines boucles s’arrêtent au trou. Pour retirer un élément, utilise plutôt table.remove, qui décale la suite.
Ajouter, retirer, chercher
La bibliothèque table fournit les fonctions essentielles :
local inventaire = {"TraineeRouge"}
-- table.insert(t, valeur) ajoute à la fin
table.insert(inventaire, "TraineeBleue")
-- table.insert(t, position, valeur) insère à une position et décale la suite
table.insert(inventaire, 1, "TraineeDoree")
print(inventaire[1], inventaire[2], inventaire[3]) --> TraineeDoree TraineeRouge TraineeBleue
-- table.remove(t, position) retire l'élément et décale la suite vers la gauche
local retire = table.remove(inventaire, 2)
print("Retiré :", retire) --> Retiré : TraineeRouge
-- table.remove(t) sans position retire le dernier élément
table.remove(inventaire)
print(#inventaire) --> 1
-- table.find(t, valeur) renvoie l'indice de la valeur, ou nil si elle est absente
print(table.find(inventaire, "TraineeDoree")) --> 1
print(table.find(inventaire, "TraineeVerte")) --> nil
Parcourir une table
L’itération générale : for ... in
La façon la plus simple de parcourir une table en Luau moderne est l’itération générale : on écrit directement la table après in. À chaque tour, on reçoit l’indice (ou la clé) et la valeur.
local etapes = {"Décollage", "Nuages", "Tempête", "Sommet"}
for indice, nom in etapes do
print(`Étape {indice} : {nom}`)
end
--> Étape 1 : Décollage
--> Étape 2 : Nuages
--> ...
Pour un tableau, l’ordre est garanti : 1, 2, 3… jusqu’à #etapes. Si tu n’as pas besoin de l’indice, la convention est de l’appeler _ (tiret bas), ce qui signifie « je l’ignore » :
local etapes = {"Décollage", "Nuages", "Tempête", "Sommet"}
for _, nom in etapes do
print(nom)
end
ipairs, pairs et la boucle numérique
Tu croiseras aussi ces écritures, notamment dans du code plus ancien. Elles restent valables :
local etapes = {"Décollage", "Nuages", "Tempête", "Sommet"}
-- La boucle numérique classique, de 1 à la longueur du tableau
for i = 1, #etapes do
print(i, etapes[i])
end
-- ipairs : parcourt les indices 1, 2, 3... (s'arrête au premier trou)
for i, nom in ipairs(etapes) do
print(i, nom)
end
-- pairs : parcourt toutes les clés (utile pour les dictionnaires)
for cle, valeur in pairs({pseudo = "Lea", etape = 3}) do
print(cle, valeur)
end
Dans cette formation, on utilise surtout l’itération générale for cle, valeur in t do, plus courte et qui marche aussi bien pour les tableaux que pour les dictionnaires.
Les dictionnaires
Un dictionnaire associe des clés (souvent des textes) à des valeurs. On accède à une valeur par sa clé, avec un point ou avec des crochets.
local prixBoutique = {
TraineeRouge = 50,
TraineeBleue = 75,
TraineeDoree = 200,
}
print(prixBoutique.TraineeRouge) --> 50 (notation avec point)
print(prixBoutique["TraineeBleue"]) --> 75 (notation avec crochets)
-- Les crochets permettent d'utiliser une clé contenue dans une variable
local objetChoisi = "TraineeDoree"
print(prixBoutique[objetChoisi]) --> 200
-- Ajouter ou modifier une entrée
prixBoutique.TraineeVerte = 60
prixBoutique.TraineeRouge = 40
-- Supprimer une entrée : on lui donne la valeur nil
prixBoutique.TraineeBleue = nil
-- Parcourir le dictionnaire (l'ordre n'est PAS garanti)
for nom, prix in prixBoutique do
print(`{nom} coûte {prix} pièces`)
end
Trois choses à retenir sur les dictionnaires :
- l’ordre de parcours est imprévisible : ne compte jamais dessus ;
- l’opérateur
#ne compte pas les entrées d’un dictionnaire (il ne mesure que la partie « tableau » numérotée, ici il donnerait 0) ; pour les compter, il faut une boucle ; - une clé absente renvoie simplement
nil, sans erreur.
Les tables imbriquées
Une valeur de table peut elle-même être une table. C’est ainsi qu’on décrit des données riches, comme les niveaux de l’Obby des Nuages :
local niveaux = {
{nom = "Les premiers nuages", nombreEtapes = 5, couleur = Color3.fromRGB(255, 255, 255)},
{nom = "La tempête", nombreEtapes = 8, couleur = Color3.fromRGB(90, 90, 120)},
{nom = "Le sommet", nombreEtapes = 4, couleur = Color3.fromRGB(255, 215, 0)},
}
print(niveaux[2].nom) --> La tempête
print(niveaux[3].nombreEtapes) --> 4
local total = 0
for _, niveau in niveaux do
total += niveau.nombreEtapes
end
print("Nombre total d'étapes :", total) --> 17
Ici, niveaux est un tableau de dictionnaires. C’est un motif très courant : la liste des niveaux est ordonnée, et chaque niveau a des propriétés nommées. On rangera ce genre de données dans le module Config à la leçon 6.
Copie ou même table ? Les références
Point crucial : une variable ne contient pas la table elle-même, mais une référence vers elle. Affecter une table à une autre variable ne la copie pas.
local original = {"TraineeRouge", "TraineeBleue"}
local autreNom = original -- PAS une copie : même table, deux noms
table.insert(autreNom, "TraineeDoree")
print(#original) --> 3 ! La table "original" a aussi changé
-- Pour obtenir une vraie copie, utilise table.clone
local copie = table.clone(original)
table.insert(copie, "TraineeVerte")
print(#original, #copie) --> 3 4 : cette fois, l'original n'a pas bougé
Les objets Roblox renvoient aussi des tables
Beaucoup de méthodes Roblox renvoient des tableaux. Par exemple, :GetChildren() renvoie un tableau contenant tous les enfants directs d’un objet, et Players:GetPlayers() la liste des joueurs connectés. C’est ce qui va nous permettre de simplifier l’Obby des Nuages.
Fil rouge : un seul script pour toutes les kill bricks
À la leçon 2, chaque kill brick contenait sa propre copie du script. Si tu veux changer le comportement, il faut modifier chaque copie : c’est fragile. La documentation Roblox conseille d’ailleurs d’éviter d’attacher des scripts directement aux objets du Workspace. Remplaçons-les par un seul Script.
- Supprime les Scripts qui se trouvent dans tes kill bricks (sinon chaque brique réagirait deux fois).
- Crée un Script nommé
KillBricksdans ServerScriptService. Dans ton projet Rojo, c’est le fichiersrc/ServerScriptService/KillBricks.server.luau: tape-le, ou demande-le à Claude Code avec le prompt de l’encadré plus bas. Voici le code à obtenir :
-- Script « KillBricks » dans ServerScriptService
-- Gère toutes les Parts rangées dans le dossier Workspace.KillBricks
local Workspace = game:GetService("Workspace")
-- WaitForChild attend que le dossier existe (détaillé à la leçon 5)
local dossierKillBricks = Workspace:WaitForChild("KillBricks")
local function surContact(autrePart)
local personnage = autrePart.Parent
local humanoid = personnage and personnage:FindFirstChildOfClass("Humanoid")
if humanoid and humanoid.Health > 0 then
humanoid.Health = 0
end
end
-- On parcourt tous les enfants du dossier
for _, killBrick in dossierKillBricks:GetChildren() do
-- On ne garde que les Parts (un Folder peut contenir autre chose)
if killBrick:IsA("BasePart") then
killBrick.Touched:Connect(surContact)
end
end
print(`{#dossierKillBricks:GetChildren()} objets dans le dossier KillBricks`)
:IsA("BasePart") vérifie que l’objet est bien une Part (de n’importe quelle forme). Dans surContact, la ligne personnage and personnage:FindFirstChildOfClass("Humanoid") utilise and comme le or de la leçon 2 : si personnage vaut nil, and s’arrête là et renvoie nil sans appeler la méthode (pas d’erreur) ; sinon, il renvoie le résultat de la recherche. Désormais, pour ajouter une kill brick, il suffit de glisser une Part dans le dossier : aucun script à copier.
Fil rouge : toutes les pièces qui tournent
Même principe pour les pièces. Supprime les Scripts placés dans chaque Piece, puis crée un Script PiecesTournantes dans ServerScriptService (fichier src/ServerScriptService/PiecesTournantes.server.luau) :
-- Script « PiecesTournantes » dans ServerScriptService
-- Fait tourner toutes les Parts du dossier Workspace.Pieces
local Workspace = game:GetService("Workspace")
local dossierPieces = Workspace:WaitForChild("Pieces")
local VITESSE_ROTATION = 90 -- degrés par seconde
while true do
local ecoule = task.wait()
local rotation = CFrame.Angles(0, math.rad(VITESSE_ROTATION * ecoule), 0)
for _, piece in dossierPieces:GetChildren() do
if piece:IsA("BasePart") then
piece.CFrame = piece.CFrame * rotation
end
end
end
On ne calcule la rotation qu’une fois par image, puis on l’applique à chaque pièce. Une seule boucle, autant de pièces que tu veux.
Tableau ou dictionnaire : comment choisir ?
| Besoin | Structure | Exemple |
|---|---|---|
| Une liste ordonnée, parcourue dans l’ordre | Tableau | Étapes du niveau, classement |
| Retrouver une valeur à partir d’un nom | Dictionnaire | Prix par objet, réglages du jeu |
| Une liste d’éléments qui ont chacun des propriétés | Tableau de dictionnaires | Niveaux, catalogue de la boutique |
| Savoir rapidement si un élément est présent | Dictionnaire dont les valeurs valent true (possedes["TraineeRouge"] = true) |
Objets déjà possédés |
Lire ce code comme un relecteur
Exercice 1 : que va afficher l’Output ?
local inventaire = {"TraineeRouge"}
local sauvegarde = inventaire
table.insert(inventaire, "TraineeBleue")
local copie = table.clone(inventaire)
table.insert(copie, "TraineeDoree")
print(#inventaire, #sauvegarde, #copie)
print(table.find(copie, "TraineeBleue"))
print(table.find(inventaire, "TraineeDoree"))
Exercice 2 : ce code fait-il ce qu’il annonce ?
-- Une IA propose ce code pour retirer toutes les traînées rouges
local inventaire = {"TraineeRouge", "TraineeRouge", "TraineeBleue"}
for i = 1, #inventaire do
if inventaire[i] == "TraineeRouge" then
table.remove(inventaire, i)
end
end
print(#inventaire, inventaire[1])
Ce qu’il faut retenir
- Une table sert de tableau (indices à partir de 1) ou de dictionnaire (clé → valeur).
#tdonne la longueur d’un tableau ;table.insert,table.removeettable.findajoutent, retirent et cherchent.- On parcourt une table avec
for cle, valeur in t do; l’ordre n’est garanti que pour la partie tableau. - Une variable contient une référence vers la table : utilise
table.clonepour une copie (superficielle). :GetChildren()renvoie un tableau d’objets : un seul script peut gérer tout un dossier de Parts, à condition de filtrer avecIsA(à vérifier dans tout code généré).
Sources et pour aller plus loin
- Tables — documentation Luau de Roblox
- Control structures (itération générale, ipairs, pairs) — documentation Luau de Roblox
- Bibliothèque standard Luau (table.find, table.insert, table.remove, table.clone) — luau.org
- Syntaxe de Luau (itération générale) — luau.org
- Instance:GetChildren — référence API
- Script types and locations (éviter les scripts attachés aux objets du Workspace) — documentation Roblox