Objectif : Découvrir pas à pas les bases de la programmation Lua avec Roblox :
- Les variables (texte et nombres)
- Les propriétés d’objets (écran, texte, Part)
- Les boucles (
foretwhile) - Les tableaux (simples et doubles)
- Le clonage et la destruction d’objets
Le fil du jeu : tu possèdes un écran géant (TableauPart) qui affiche des messages, et un cube magique (Part) qui va grandir, changer de couleur, devenir invisible… et même se multiplier en pyramide inversée !
Règle du jeu : à chaque étape, essaye d’écrire le code, teste, contrôle ce qui est affiché, puis réponds au QCM avant de passer à la suite !
Étape 0 : Préparer le terrain dans Roblox Studio
Avant de coder, construis la scène :
- Dans
Workspace, crée un dossier nomméFolder. - Dans ce dossier :
- Une
PartnomméeTableauPart: aplatie comme un écran (ex:Size = Vector3.new(12, 8, 0.5)), avecAnchored = true. - Une
PartnomméePart: un cube visible (Size = Vector3.new(4, 4, 4)), avecAnchored = true.
- Une
- Sur
TableauPart, ajoute (clic droit → Insert Object) :- Un
SurfaceGui(nomme-leSurfaceGui). - Dans le
SurfaceGui, unTextBox(nomme-leTextBox) : étire-le sur tout l’écran avecSize = {1,0},{1,0}.
- Un
- Crée un
ScriptdansServerScriptService: c’est là que tu colleras le code, étape par étape.


En haut du script, ces lignes (elles ne changent plus jamais) :
-- Récupérer les objets de la scène
local folder = workspace:WaitForChild("Folder")
local tableauPart = folder:WaitForChild("TableauPart")
local surfaceGui = tableauPart:WaitForChild("SurfaceGui")
local screen = surfaceGui:WaitForChild("TextBox") -- notre écran d'affichage
local part = folder:WaitForChild("Part") -- notre cube magique
Convention : comme dans tous nos tutoriels, les noms de variables sont en anglais (screen, firstName…) et les commentaires en français.
Étape 1 : Afficher un message (les propriétés d’un objet)
But : écrire « Bonjour » sur l’écran géant.
Explication : un objet Roblox (comme notre TextBox) possède des propriétés : sa couleur, sa taille… et son texte (Text). Pour changer une propriété, on écrit objet.propriete = valeur.
-- ÉTAPE 1 : Affiche un Bonjour à l'écran
screen.Text = "Bonjour"
Teste ! Lance le jeu.
Contrôle : tu dois voir « Bonjour » s’afficher sur l’écran géant. Sinon, vérifie que ton TextBox s’appelle bien TextBox et que le script pointe vers le bon objet.
QCM :
- Comment change-t-on le texte affiché dans le
TextBox?- a)
screen.Bonjour = Text - b)
print("Bonjour") - c)
screen.Text = "Bonjour"
- a)
Textest… ?- a) Une propriété du
TextBox. - b) Une boucle.
- c) Un joueur.
- a) Une propriété du
Étape 2 : Les variables texte et la concaténation
But : afficher « Bonjour patrick ! » (avec ton prénom !).
Explication : une variable, c’est une boîte avec une étiquette qui contient une valeur. Pour assembler des morceaux de texte, on utilise .. (deux points) : c’est la concaténation.
-- ÉTAPE 2 : Renseigne une variable pour afficher ton prénom
task.wait(2) -- petite pause de 2 secondes
local firstName = "patrick" -- remplace par TON prénom !
screen.Text = "Bonjour " .. firstName .. " !"
Teste ! Contrôle : l’écran affiche d’abord « Bonjour » (2 secondes), puis « Bonjour tonprénom ! ». Attention : il y a un espace dans "Bonjour "; essaie sans espace pour voir la différence !
QCM :
- Que fait
"Bonjour " .. firstName?- a) Il colle les deux textes bout à bout (concaténation).
- b) Il les additionne comme des nombres.
- c) Il supprime le premier texte.
- Que fait
task.wait(2)?- a) Il supprime 2 objets.
- b) Il met le script en pause pendant 2 secondes.
- c) Il écrit 2 fois le texte.
Étape 3 : Modifier les propriétés de l’écran et du texte
But : rendre l’écran coloré et le texte stylé.
Explication : on peut modifier plein de propriétés d’un objet : couleur de fond (BackgroundColor3), couleur du texte (TextColor3), bordure, taille du texte… Color3.fromRGB(rouge, vert, bleu) fabrique une couleur avec 3 nombres de 0 à 255.
-- ÉTAPE 3 : Modifie les propriétés de l'écran et du texte
screen.BackgroundColor3 = Color3.fromRGB(85, 255, 255) -- fond cyan
sreen.TextColor3 = Color3.fromRGB(50, 50, 100) -- gris bleu
screen.BorderMode = Enum.BorderMode.Inset -- style de bordure
screen.BorderColor3 = Color3.fromRGB(255, 0, 0) -- bordure rouge
screen.BorderSizePixel = 20 -- épaisseur de la bordure
screen.TextScaled = true -- texte agrandi automatiquement
screen.TextWrapped = true -- texte qui passe à la ligne
screen.TextXAlignment = Enum.TextXAlignment.Center -- texte centré
Teste ! Contrôle : fond cyan, texte jaune, bordure rouge épaisse, texte centré et plus grand. Amuse-toi : change les 3 nombres de fromRGB et observe ! Que donne Color3.fromRGB(255, 0, 0) ? Et Color3.fromRGB(0, 0, 255) ?
QCM :
- Que représente les 3 nombres de
Color3.fromRGB(...)?- a) Les quantités de rouge, de vert et de bleu (de 0 à 255).
- b) La taille de l’écran.
- c) L’heure.
- Que fait
screen.TextScaled = true?- a) L’écran disparaît.
- b) Le texte s’agrandit automatiquement pour remplir l’espace.
- c) Le texte devient bleu.
Étape 4 : Les variables nombre
But : afficher ton âge à l’écran.
Explication : une variable peut contenir du texte ("patrick") ou un nombre (12). Attention au piège : pour coller un nombre à du texte, on utilise quand même .. !
-- ÉTAPE 4 : Renseigne ton âge dans une variable et affiche-le
task.wait(2)
local age = 12 -- remplace par TON âge !
screen.Text = screen.Text .. "\nJ'ai " .. age .. " ans"
Nouveauté : \n = un saut de ligne dans le texte (le message s’écrit en dessous du précédent).
Teste ! Contrôle : le message « J’ai X ans » apparaît en dessous du message précédent. Si tout s’affiche sur une seule ligne, vérifie ton \n.
QCM :
- Que fait
"\n"dans un texte ?- a) Il affiche un « n ».
- b) Il efface le texte.
- c) Il saute à la ligne suivante.
Réponse : a)
- Peut-on coller un nombre à du texte avec
..?- a) Oui,
.. " ans"fonctionne avec une variable nombre. - b) Non, jamais.
- c) Seulement le lundi.
- a) Oui,
Étape 5 : À toi de jouer — une variable de ton choix
But : afficher une information de ton choix (ex: « Fille » ou « Garçon », ou ta classe).
Explication : c’est le même principe qu’avant. À toi d’écrire le code sans copier ! Indice : crée une variable texte, puis concatène-la avec \n à la suite.
-- ÉTAPE 5 : Renseigne une information et affiche-la
task.wait(2)
local gender = "Garçon" -- ou "Fille"... ou invente ta variable !
screen.Text = screen.Text .. "\n" .. gender
Teste ! Contrôle : ta nouvelle ligne s’affiche sous les précédentes, sans effacer le reste.
QCM :
- Que se passe-t-il si tu écris
screen.Text = gender(sans concaténation) ?- a) Tout le texte précédent est remplacé par ta variable.
- b) Ta variable s’ajoute à la fin.
- c) Rien ne s’affiche.
Étape 6 : Les nombres et l’addition (ton inventaire)
But : imagine que tu récupères une épée, un laser et une lampe, et calcule le total des points de ton inventaire.
Explication : avec des variables nombre, on peut calculer : +, -, * (multiplié), / (divisé).
-- ÉTAPE 6 : Calcule le total des points de l'inventaire
task.wait(2)
local sword = 10 -- points de l'épée
local laser = 50 -- points du laser
local lamp = 2 -- points de la lampe
local total = sword + laser + lamp -- le calcul !
screen.Text = screen.Text .. "\nTotal inventaire : " .. total
Teste ! Contrôle : l’écran affiche « Total inventaire : 62 ». Vérifie le calcul de tête : 10 + 50 + 2 = 62 ?
QCM :
- Que vaut
totalsisword = 10,laser = 50,lamp = 2?- a) 62
- b) 10502
- c) 60
- Que fait
local total = sword + laser + lamp?- a) Il colle les trois textes.
- b) Il additionne les trois variables et range le résultat dans
total. - c) Il supprime les variables.
Étape 7 : Un vrai calcul (le voyage en vaisseau)
But : ton vaisseau part avec un réservoir vide, tu achètes 100 litres, puis tu visites 3 villes qui consomment chacune 30 litres. Combien reste-t-il ?
Explication : on peut combiner plusieurs opérations, et même réutiliser une variable avec =. Les parenthèses ( ) forcent le calcul à se faire en priorité.
-- ÉTAPE 7 : Calcule le carburant restant
task.wait(2)
local fuelTank = 0 -- réservoir vide au départ
local fuelBought = 100 -- litres achetés
local trips = 3 -- nombre de déplacements
local fuelPerTrip = 30 -- litres consommés par déplacement
fuelTank = fuelTank + fuelBought - (trips * fuelPerTrip) -- le calcul !
screen.Text = screen.Text .. "\nReste dans mon réservoir : " .. fuelTank
Teste ! Contrôle : l’écran affiche 10 (100 – 90 = 10). Enlève les parenthèses autour de trips * fuelPerTrip : le résultat est-il le même ? Pourquoi ? (Indice : sans parenthèses, le calcul se fait de gauche à droite !)
QCM :
- Pourquoi met-on des parenthèses autour de
trips * fuelPerTrip?- a) Pour que la multiplication se fasse avant la soustraction.
- b) Pour décorer le code.
- c) Pour afficher le texte.
Étape 8 : La boucle for (compteur et décompte)
But : afficher un compteur de 1 à 10, puis un décompte de 10 à 1.
Explication : une boucle for répète un bloc de code. for i = 1, 10 do signifie : « pour i allant de 1 à 10 ». La variable i change à chaque tour ! Et for i = 10, 1, -1 compte à l’envers grâce au pas de -1.
-- ÉTAPE 8a : Compteur de 1 à 10
task.wait(2)
local baseText = screen.Text .. "\n"
for i = 1, 10 do
screen.Text = baseText .. "Attente : " .. i .. " seconde(s)"
task.wait(0.3)
end
-- ÉTAPE 8b : Décompte de 10 à 1
for i = 10, 1, -1 do -- pas de -1 : on compte à l'envers !
screen.Text = baseText .. "Attente : " .. i .. " seconde(s)"
task.wait(0.3)
end
Teste ! Contrôle : le chiffre affiché monte 1, 2, 3… 10 puis redescend 10, 9… 1. Remarque : on a préparé baseText avant la boucle pour ne pas coller 10 fois la phrase !
QCM :
- Combien de fois le code dans
for i = 1, 10 dos’exécute-t-il ?- a) 10 fois.
- b) 1 fois.
- c) 11 fois.
- Que fait le
-1dansfor i = 10, 1, -1 do?- a) Il fait diminuer
ide 1 à chaque tour (décompte). - b) Il répète la boucle à l’infini.
- c) Il affiche -1 à l’écran.
- a) Il fait diminuer
Étape 9 : Les tableaux (ton inventaire en liste)
But : ranger les valeurs de l’inventaire dans un tableau et les afficher une par une.
Explication : un tableau ({ }) range plusieurs valeurs dans une seule variable. pairs parcourt le tableau et donne l’index (i, la position) et la valeur (item).
-- ÉTAPE 9 : Affiche l'inventaire avec une boucle
task.wait(2)
screen.Text = baseText .. "\n"
local inventory = {sword, laser, lamp} -- tableau avec les 3 valeurs
for i, item in pairs(inventory) do
screen.Text = screen.Text .. "Objet " .. i .. " : " .. item .. "\n"
end
Teste ! Contrôle : l’écran affiche 3 lignes : « Objet 1 : 10 », « Objet 2 : 50 », « Objet 3 : 2 ».
QCM :
- Que vaut
inventory[1]?- a) Le nombre de cases.
- b) La première valeur du tableau (10, la valeur de
sword). - c) Une erreur.
- Dans
for i, item in pairs(inventory) do, que vautitem?- a) La valeur de la case courante du tableau.
- b) Le nom du tableau.
- c) Toujours 1.
Étape 10 : Le tableau double (objet ET valeur)
But : afficher le nom de chaque objet et sa valeur. Un tableau dans un tableau !
Explication : chaque case d’un tableau peut contenir… un autre tableau ! {{"sword", 10}, {"laser", 50}}. Pour lire la case 1 d’un sous-tableau : item[1].
-- ÉTAPE 10 : Affiche les noms et les valeurs de l'inventaire
task.wait(2)
screen.Text = baseText .. "\n"
inventory = {{"sword", sword}, {"laser", laser}, {"lamp", lamp}} -- tableau double
for i, item in pairs(inventory) do
screen.Text = screen.Text .. i .. ") " .. item[1] .. " : " .. item[2] .. "\n"
end
baseText = screen.Text -- on mémorise pour la suite
Teste ! Contrôle : l’écran affiche : « 1) sword : 10 », « 2) laser : 50 », « 3) lamp : 2 ». Le nom ET la valeur !
QCM :
- Que vaut
item[2]dans la boucle ?- a) Le nom de l’objet.
- b) La position dans le tableau.
- c) La valeur (le nombre de points) de l’objet courant.
- Comment s’appelle un tableau qui contient d’autres tableaux ?
- a) Un tableau double (imbriqué).
- b) Une boucle.
- c) Une propriété.
Étape 11 : La boucle while (la jauge d’énergie)
But : faire monter une jauge d’énergie jusqu’à 100, barre par barre.
Explication : la boucle while (« tant que ») répète un code tant qu’une condition est vraie. Ici : tant que l’énergie est inférieure au maximum, on ajoute 10.
-- ÉTAPE 11 : Charge la jauge d'énergie
task.wait(2)
local energy = 10 -- énergie de départ
local maxEnergy = 100 -- énergie maximale
screen.Text = screen.Text .. "Energie : "
while energy < maxEnergy do -- TANT QUE energy < 100
energy = energy + 10 -- ajouter 10
screen.Text = screen.Text .. "▄" -- une barre de plus (Alt+220)
task.wait(0.3)
end
Teste ! Contrôle : les barres « ▄ » s’ajoutent une par une, puis s’arrêtent d’elles-mêmes quand l’énergie atteint 100. La boucle s’est toute seule arrêtée : c’est la condition qui l’a décidée !
QCM :
- Quand la boucle
whiles’arrête-t-elle ?- a) Quand la condition devient fausse (ici, quand
energyatteint 100). - b) Après 10 secondes.
- c) Jamais.
- a) Quand la condition devient fausse (ici, quand
- Quelle est la différence avec la boucle
for?- a) Aucune.
- b)
forrépète un nombre de fois connu ;whilerépète jusqu’à une condition. - c)
whilene marche que sur les écrans.
Étape 12 : Transformer le cube (taille et couleur)
But : faire grandir, rétrécir, changer la couleur du cube magique… en boucle !
Explication : la Size d’une Part est un Vector3 (largeur, hauteur, profondeur) : on peut l’additionner ou la soustraire avec += et -=. La couleur est faite avec Color3.fromRGB : si les 3 nombres sont égaux, on obtient un gris (0 = noir, 255 = blanc) !
-- ÉTAPE 12a : Fais grandir le cube, puis rétrécir
task.wait(2)
for i = 1, 10 do
part.Size += Vector3.new(i, i, i) -- le cube grossit de plus en plus fort !
task.wait(0.3)
end
for i = 1, 10 do
part.Size -= Vector3.new(i, i, i) -- et il rétrécit
task.wait(0.3)
end
-- ÉTAPE 12b : Du noir au blanc (le gris)
for i = 0, 255 do
part.Color = Color3.fromRGB(i, i, i) -- gris qui s'éclaircit
task.wait(0.01)
end
-- ÉTAPE 12c : Une couleur vivante (du noir au rouge)
for i = 0, 255 do
part.Color = Color3.fromRGB(i, 160, 160) -- rouge qui monte, vert/bleu fixes
task.wait(0.01)
end
Teste ! Contrôle : le cube grossit de plus en plus vite (car i augmente à chaque tour !), rétrécit, passe du noir au gris clair, puis prend une teinte rouge. Modifie le 160 : que se passe-t-il avec Color3.fromRGB(i, 0, 0) ?
QCM :
- Pourquoi le cube grandit-il de plus en plus vite dans la première boucle ?
- a) Parce que
task.waitraccourcit. - b) Parce que
iaugmente à chaque tour, et on ajouteVector3.new(i, i, i). - c) Parce qu’il est magique.
- a) Parce que
- Que donne
Color3.fromRGB(100, 100, 100)?- a) Un gris moyen.
- b) Du rouge pur.
- c) Du blanc pur.
Étape 13 : Invisible puis visible (la transparence)
But : faire disparaître le cube puis le faire réapparaître.
Explication : la propriété Transparency va de 0 (opaque) à 1 (invisible). Deux boucles while parfaites pour ça !
-- ÉTAPE 13a : Rend le cube transparent (disparition)
while part.Transparency < 1 do
part.Transparency += 0.1 -- un peu plus transparent...
task.wait(0.1)
end
-- ÉTAPE 13b : Rend-le opaque (réapparition)
task.wait(2)
while part.Transparency > 0 do
part.Transparency -= 0.1 -- un peu plus opaque...
task.wait(0.1)
end
Teste ! Contrôle : le cube s’efface progressivement puis réapparaît tout doucement, comme un fantôme !
QCM :
- Quand une Part est-elle complètement invisible ?
- a) Quand
Transparency = 0. - b) Quand
Transparency = 1. - c) Quand
Transparency = 255.
- a) Quand
- Que fait
part.Transparency += 0.1?- a) Il ajoute 0.1 à la transparence actuelle (avec
+=). - b) Il remplace la transparence par 0.1.
- c) Il change la taille.
- a) Il ajoute 0.1 à la transparence actuelle (avec
Étape 14 : Le clonage : construis une pyramide inversée !
But : cloner le cube 10 fois pour construire une pyramide inversée : chaque nouvel étage est plus large que le précédent, posé au-dessus.
Explication : part:Clone() crée une copie exacte de la Part. On la modifie ensuite (position, taille) puis on l’attache au dossier avec .Parent. Sans .Parent, l’objet reste invisible ! Attention aussi : chaque copie doit avoir un nom différent (« Part1 », « Part2″…) pour pouvoir la retrouver ensuite.
-- ÉTAPE 14 : Construis la pyramide inversée
task.wait(3)
screen.Text = baseText -- on nettoie l'écran
for i = 1, 10 do
local newPart = part:Clone() -- une copie du cube
newPart.Position += Vector3.new(0, newPart.Size.Y * i, 0) -- posée plus haut à chaque fois
newPart.Size += Vector3.new(i * 3, 0, i * 3) -- de plus en plus large !
newPart.Parent = folder -- ATTACHE la copie au monde
newPart.Name = "Part" .. i -- nom unique : "Part1", "Part2"...
task.wait(1)
end
Teste ! Contrôle : un nouveau bloc apparaît chaque seconde, posé au-dessus du précédent, et de plus en plus large : la pyramide pointe vers le bas ! Regarde dans l’Explorer : les Part1 à Part10 sont bien dans Folder.
QCM :
- Que fait
part:Clone()?- a) Il crée une copie identique de la Part.
- b) Il supprime la Part.
- c) Il change la couleur.
- Que se passe-t-il si on oublie
newPart.Parent = folder?- a) Le jeu plante.
- b) La copie existe en mémoire mais n’apparaît pas dans le jeu.
- c) Rien, c’est la même chose.
- Pourquoi
newPart.Name = "Part" .. i?- a) Pour donner un nom unique à chaque copie et la retrouver plus tard.
- b) Pour la détruire.
- c) Pour changer sa couleur.
Étape 15 : La destruction : démolis la pyramide à l’envers !
But : détruire les blocs du haut vers le bas (ordre inverse).
Explication : :Destroy() supprime définitivement un objet. Pour retrouver chaque bloc par son nom, on utilise FindFirstChild : "Part" .. i fabrique le nom à chercher !
-- ÉTAPE 15 : Détruis les blocs dans l'ordre inverse
task.wait(3)
for i = 10, 1, -1 do -- du dernier au premier !
local block = folder:FindFirstChild("Part" .. i) -- retrouve le bloc par son nom
if block then
block:Destroy() -- ... et détruis-le !
end
task.wait(1)
end
task.wait(3)
Teste ! Contrôle : les blocs disparaissent un par un, du haut vers le bas. À la fin, l’Explorer ne contient plus que TableauPart et Part !
- Que fait
folder:FindFirstChild("Part" .. i)?- a) Il détruit la Part.
- b) Il cherche dans le dossier l’objet nommé « Part1 », « Part2″… selon la valeur de
i. - c) Il crée une Part.
- Pourquoi la boucle va de 10 à 1 avec un pas de
-1?- a) Pour aller plus vite.
- b) Par hasard.
- c) Pour détruire les blocs dans l’ordre inverse de leur création (du haut vers le bas).
- Pourquoi vérifie-t-on
if block thenavant de détruire ?- a) Pour éviter une erreur si le bloc n’existe pas (il retourne
nil). - b) Pour changer sa couleur.
- c) Ce n’est pas utile.
- a) Pour éviter une erreur si le bloc n’existe pas (il retourne
Résumé des concepts découverts
| Concept | Description | Exemple |
|---|---|---|
| Propriétés | Les réglages d’un objet. | screen.Text, part.Color |
| Variable texte / nombre | Une boîte étiquetée contenant une valeur. | local firstName = "patrick" |
Concaténation .. | Coller des textes (et nombres) ensemble. | "J'ai " .. age |
\n | Saut de ligne dans un texte. | screen.Text .. "\n" |
Color3.fromRGB | Fabriquer une couleur (rouge, vert, bleu : 0-255). | Color3.fromRGB(85, 255, 255) |
| Calculs | ‘+, -, *, / et les parenthèses. | fuelTank + fuelBought - (trips * fuelPerTrip) |
Boucle for | Répéter un nombre de fois connu (avec pas négatif pour décompter). | for i = 10, 1, -1 do |
Boucle while | Répéter tant qu’une condition est vraie. | while energy < maxEnergy do |
| Tableau | Une liste de valeurs. | {sword, laser, lamp} |
| Tableau double | Un tableau de tableaux (nom + valeur). | {{"sword", 10}} |
pairs | Parcourir un tableau (index + valeur). | for i, item in pairs(inventory) do |
‘+= et -= | Ajouter / retirer à une valeur. | part.Size += Vector3.new(i, i, i) |
Clone() | Copier un objet. | part:Clone() |
Destroy() | Supprimer un objet. | block:Destroy() |
FindFirstChild | Retrouver un objet par son nom. | folder:FindFirstChild("Part" .. i) |
Défi final :
- Personnalise l’écran : affiche ton prénom, ton âge, ton inventaire imaginé (5 objets dans un tableau double !).
- Crée un escalier : au lieu d’une pyramide inversée, fais des marches qui montent en décalant aussi sur l’axe X (
Vector3.new(i * 5, i * 2, 0)).
Félicitations ! Tu viens de découvrir presque toutes les bases de la programmation Lua : variables, conditions, boucles, tableaux, objets et propriétés. Tous les grands jeux Roblox sont construits avec ces mêmes briques !
