Aller au contenu

Année 4. Atelier Minetest-Python avec Miney

Lundi 10 juin 2024

Introduction

Cette présentation rappelle le contexte dans lequel se place cet atelier et peut servir de compagnon au texte qui suit.

Le projet UNEJ

Durant quatre années (de 2020 à 2024), des collégiens et lycéens de Seine-Saint-Denis ont participé au projet Urbanités Numérique en Jeux 2024. Pendant ces quatre années, ces élèves se sont initiés à l’urbanisme en concevant des projets d’aménagement de l’échelle de leur lycée à l’échelle de leur quartier. Par exemple, au lycée Jacques Brel, les élèves ont proposé un aménagement de la cour du lycée et d’un espace vert situé en face de la future gare des Six Routes à la Courneuve (le Square du Moulin Fayvon).

Chaque projet d’aménagement requiert la préparation d’une carte Minetest correspondant à un quartier de Seine-Saint-Denis sur laquelle les élèves peuvent modéliser collectivement en trois dimensions leurs projets d’aménagement. La préparation des cartes est réalisée à l’aide du générateur automatique appelé Minecraft® à la Carte mis à disposition par l’IGN (Institut Géographique National).

La préparation des cartes Minetest

Les cartes Minetest obtenues à l’aide de Minecraft® à la Carte sont déjà très riches : les données de l’IGN permettent de reproduire dans Minest l’essentiel du relief, des bâtiments, de la végétation et voies de circulation d’un quartier. Cependant, le niveau de détail est parfois insuffisant pour fournir un contexte de modélisation suffisemment réaliste et engageant pour les élèves. Par ailleurs, l’outil de l’IGN ne permet de générer qu’une carte correspondant à l’état présent du quartier. Il n’est pas possible d’inclure sur la carte un futur aménagement proposé par des architechtes et des urbanismes par exemple.

Ainsi, de nombreuses heures de travail peuvent être nécessaires au fignolage de la carte Minetest avant de pouvoir accueillir les projets d’aménagement des élèves. Cela représente une perte de temps importante (des dizaines d’heures de modélisation manuelle bloc à bloc !) pour l’enseignant ou/et pour les élèves. En effet, la finalité du projet n’était ni de reproduire l’existant ni de recopier un plan d’architecte mais véritablement d’imaginer collectivement puis modéliser un projet d’aménagement original et personnel.

Miney

Afin de gagner du temps dans la phase de fignolage de la carte Minetest, en particulier pour l’ajout de végatation et de futurs bâtiments, il nous a paru essentiel que ces tâches soient automatisées pour de futurs projets par une approche programmatique. Python étant le langage de programmation principal enseigné au lycée, nous avons recherché une solution de ce côté et trouvé l’incontournable Miney.

miney est un module Python permettant d’interragir avec Minetest à l’aide de programmes Python. On dit que miney est une API Python pour Minetest. API siginife Application Programming Interface ou en français “Interface de programmation d’une Application”.

Déroulement de l’atelier

  1. Mise en place de l’environnement de travail.
  2. Prise en main des commandes Python de miney permettant d’interagir avec la carte Minetest et le personnage ;
  3. Présentation des objectifs de l’atelier. Écrire un module Python permettant de construire de manière automatisée une grille d’arbres en respectant le relief et sans détruire les bâtiments préexistants sur la carte.
  4. Développement du module en local.
    • Lister et spécifier les fonctions du module
    • coder et tester chaque fonction
  5. Tester le module sur le serveur du projet : carte Minest contenant le village olympique

Phase 1. Mise en place de l’environnement de travail

La suite est dédiée aux ordinateurs tournant sous Windows. Pour Linux, veuillez vous référer à cette page.

Téléchargement de Miney

Miney est distribué comme un package tout-en-un contenant :

  • le jeu minetest ;
  • une distribution récente de Python qui comprend le module miney.

Pour Windows, le dossier à télécharger contient des exécutables, aucune installation n’est requise. Cela en fait une solution idéale pour l’utilisation en classe par des élèves qui ne possèdent pas les droits d’administration de leurs PC.

  1. Avant le téléchargement, vérifier que le paramétrage de votre navigateur Web vous permet de choisir systématiquement le dossier de téléchargement. Par exemple, ce tutoriel explique comment faire dans Mozilla Firefox pour garantir ce comportement.
  2. Télécharger le dossier Miney à cette adresse. Les PC actuels possèdent en majorité un processeur en x64 (64 bits). Cliquez donc dans la liste sur le lien miney_windows_x64.zip.

    Pour les PC anciens

    Si vous avez un très vieux PC, consulter la fiche de son processeur. S’il est en x86 (32 bits) cliquez sur le second lien miney_windows_x86.zip .

  3. Dans la fenêtre de dialogue choisir le dossier de téléchargement. Je vous recommande de choisir le dossier racine de votre espace utilisateur. Pour cela, dans la barre latérale, cliquer sur Ce PC. Double cliquez ensuite sur Windows (C:) puis sur Utilisateurs (ou Users) puis sur le dossier portant votre nom. Ce dernier dossier sera désigné dans la suite du tutoriel par votrenom. Cliquez ensuite sur le bouton télécharger.

  4. Suivre le téléchargement dans votre navigateur et le relancer si nécessaire.

Décompression du dossier Miney

  1. Lancer l’explorateur de fichier Windows.
  2. Vérifier que l’affichage des noms de fichiers inclu leurs extensions (par exemple *.pdf, *.txt ou *.zip). Pour cela, dans le menu de l’explorateur de fichier, cliquer sur Afficher. Dans le menu contextuel, cliquer à nouveau sur Afficher puis vérifier que l’option Extensions des noms de fichiers est activée (tick à gauche) sinon activer l’option en cliquant dessus.
  3. Naviguer dans l’arborescence de fichier jusqu’au dossier suivant :

    Ce PC > Windows (C:) > Utilisateurs > votrenom

  4. Cliquez-droit sur le fichier zippé miney_windows_x64.zip et choisir Extraire tout... dans le menu contextuel.

  5. Dans la fenêtre de dialogue qui s’est ouverte, cliquer simplement sur le bouton Extraire sans modifier le dossier de destination puis attendre la fin de l’extraction (quelques minutes).
  6. Retourner dans le dossier Ce PC > Windows (C:) > Utilisateurs > votrenom. Le dossier décompressé miney_windows_x64 (sans le .zip) doit normalement y figurer. On peut maintenant supprimer le dossier zippé devenu inutile. Pour cela, simple-cliquer sur le fichier zippé miney_windows_x64.zip. Dans le menu cliquez sur l’icône corbeille. Se rendre sur le bureau de l’ordinateur puis cliquez droit sur la corbeille et vider-là.

Premier lancement de Miney

  1. Lancer l’explorateur de fichier Windows.
  2. Naviguer dans l’arborescence de fichier jusqu’au dossier suivant :

    Ce PC > Windows (C:) > Utilisateurs > votrenom > miney_windows_x64 > miney_x64

  3. Double-cliquer sur miney_launcher.exe

  4. Une fenêtre de dialogue dont le titre est “Windows protégé votre ordinateur ” est susceptible de s’ouvrir. Si c’est le cas cliquer sur Informations complémentaires puis sur le bouton Exécuter quand même.
  5. La fenêtre de lancement de Miney apparaît.
  6. Dans la barre des tâches tout en bas de l’écran, cliquer-droit sur l’icône minetest puis dans le menu contextuel choisir Épingler à la barre des taches pour conserver un raccourci direct vers Miney.
  7. Cliquer sur le bouton “Quickstart”
  8. Minest se lance ainsi que IDLE (une IDE basique pour Python). Un IDE de l’angalais Integrated Development Environnement (Environnement de développement intégré en français) est un logiciel permettant d’écrire et d’exécuter des commandes et des programmes (ici en Python).
  9. Pour améliorer l’affichage, positionner IDLE dans la coin haut droit de l’écran. Pour cela, survoler le carré en haut à droite de la fenêtre puis cliquer sur le coin haut droite dans le troisième schéma de division d’écran.
  10. Cliquez sur la fenêtre de Minetest et mettre en pause en appuyant sur la touche Échap.
  11. Positionner la fenêtre de Minetest dans la partie gauche de l’écran en suivant la même procédure que pour IDLE.
  12. cliquer dans IDLE et entrer dans la console l’instruction Python suivante (ne pas réécrire le prompt (ou invite de commande) >>>) :
    >>> import miney
    
    L’exécuter en appuyant sur le bouton Entrée. Vous venez de charger en mémoire le module miney.
  13. Entrer et exécuter maintenant la commande suivante qui permet de créer un objet Python permettant d’interragir avec Minetest.
    >>> mt = miney.Minetest()
    
    Cet objet est nommé par convention mt mais tout autre nom serait possible.
  14. Afin de vérifier que l’interraction fonctionne, nous allons modifier l’heure de la journée dans Minetest. Pour cela exécuter successivement les instruction suivantes (la première change l’heure à minuit, la seconde à midi). Observer le résultat dans Minetest.
    >>> mt.time_of_day = 0
    >>> mt.time_of_fay = 0.5
    
  15. On peut également écrire un véritable programme Python. Pour cela, dans le menu aller à File > New File. La fenêtre d’un fichier de programame sans titre apparaît. Commencez par l’enregistrer avec File > Save As.... L’enregistrer dans le dossier par défaut (celui de miney) sous le nom premiers_pas.py.
  16. Positionner la fnêtre de programme de IDLE dans le coin bas droit de l’écran.
  17. Copier_coller dans le fichier de programme le programme Python suivant :
    import miney
    mt = miney.Minetest()
    # On envoie un message à tout le monde dans le chat.
    mt.chat.send_to_all("Bonjour tout le monde !")
    # Les joueurs présents dans la carte sont contenus dans la liste
    # `mt.player`. On affecte à la variable `mon_joueur` l'unique joueur présent
    # C'est-à-dire nous, le premier et unique élément de cette liste (rang 0).
    mon_joueur = mt.player[0]
    # On affecte une vitesse de vol de 5 à notre joueur.
    mon_joueur.fly = 5
    # On ajoute 99 noeuds de terre (dirt) dans l'inventaire de notre joueur.
    mon_joueur.inventory.add(mt.node.type.default.dirt, 99)
    # On retire 50 noeuds de terre dans l'inventaire de notre joueur.
    mon_joueur.inventory.remove(mt.node.type.default.dirt, 50)
    # On affiche les coordonnées de notre joueur. Remarquer qu'il s'agit d'un
    # dictionnaire. Attention :
    # - l'altitude est y ;
    # - vers l'Est est x ;
    # - et vers le Nord est z.
    print(mon_joueur.position)
    # On peut par exemple afficher l'altitude du joueur :
    print(mon_joueur.position['y'])
    # On récupère ("get" en anglais) le noeud situé à la position du joueur
    noeud = mt.node.get(mon_joueur.position)
    # On affiche les informations sur ce noeud. Remarquer qu'il s'agit d'un
    # dictionnaire.
    print(noeud)
    # On peut par exemple obtenir sa nature (puisque l'on vole il y a de forte
    # chance que le noeud soit de l'air !).
    print(noeud['name'])
    # On modifie ("set" en anglais) la nature de ce noeud.
    mt.node.set(noeud, 'default:glass')
    # On fait monter le joueur de 10 mètres vers le haut
    mon_joueur.position['y'] += 10
    
  18. Commencer par activer le vol dans Minetest. N’hesitez pas à consulter/modifier les touches de contrôle du personnage dans Minetest (Échap > Changer les touches). Enregistrer (Ctrl + S) puis exécuter le programme (F5). Remarque Pour observer le résultat dans Minetest en sortant du mode pause voici comment procéder. Cliquer sur la fenêtre de Minetest, sorter du mode pause. Poser quatre doigts sur le pavé tactile et les faire glisser vers le haut pour faire apparaître la galerie des fenêtre. Cliquer sur la fenêtre de programme d’IDLE. Exécuter ensuite le programme.
  19. Observer le résultat dans Minetest et dans la console. Relancer plusieurs fois le programme et observer l’altitude du joueur se modifier.
Utiliser un autre IDE (utilisateurs avancés)

IDLE etant relativement basique dans ses fonctionnalités, on peut souhaiter utiliser un IDE plus avancé. Ce tutoriel montre comment travailler dans Visual Studio Code (ou son équivalent libre et open source vscodium).

  1. Si ce n’est pas déjà fait, installer Visual Studio Code depuis le Windows Store.
  2. Lancer Visual Studio Code et cliquer sur l’icône quatre carré à gauche (menu des extensions).
  3. Dans le menu des extensions et tapper Python puis choisir la première proposition dans la liste et l’installer.
  4. Il faut maintenant choisir le bon interpréteur Python : celui du package de Miney. Pour cela se rendre dans le menu de Visual Studio Code à View > Command Palette .... Dans le cadre de texte, entrer Python: Select Interpreter et cliquer dessus dans la liste des propositions.
  5. Cliquer ensuite sur Enter interpreter path puis sur Find.... Dans la fenêtre de dialogue, naviguer dans l’arborescence suivante : Ce PC > Windows (C:) > Utilisateurs > votrenom > miney_windows_x64 > miney_x64 > Python puis double-cliquer python.exe.
  6. Si ce n’est pas déjà le cas fermer toutes les fenêtre d’IDLE et positionner Visual Studio Code dans la partie droite de l’écran.
  7. Ouvrez le dossier contenant premiers_pas.py dans Visual Studio Code. Pour cela, dans le menu de Visual Studio Code File > Open Folder... puis dans la fenêtre de dialogue retrouver le dossier et simple-cliquer dessus puis cliquer sur le bouton Selectionner un dossier.
  8. Faire apparaîtr l’onglet des fichiers en cliquant sur l’icône fichier en en haut à gauche. Simple-cliquer sur premiers_pas.py puis cliquer sur l’icône lecture en haut à droite.

Phase 2. Exercices de prise en main.

Pour les exercices de prise en main qui suivent, des corrections sont proposées. Ne les consulter pas immédiatement. Demandez de l’aide au professeur si nécessaire.

Exerice 1. Construire une ligne

  1. Créer un nouveau fichier de programme nommé exercice1.py.
  2. Copier-coller dedans le code à compléter ci-dessous.
    import miney
    mt = miney.Minetest()
    mon_joueur = mt.player[0]
    mon_joueur.fly = 5
    pos = mon_joueur.position
    for i in range(...):
        # On récupère le noeud de la position courante du joueur.
        noeud = mt.node.get(...)
        # On remplace le noeud courant par du verre par défaut.
        mt.node.set(..., ...)
        # On met à jour la position en se décalant de 1 mètre.
        pos[x] += ...
    
  3. Compléter le programme préédent afin de faire construire au personnage une ligne horizontale de 1O noeuds de long commençant à la position courante du joueur. Les noeuds seront du type verre par défaut. Consulter le programme premiers_pas.py pour vous aider.
Correction
import miney
mt = miney.Minetest()
mon_joueur = mt.player[0]
mon_joueur.fly = 5
pos = mon_joueur.position
for i in range(10):
    # On récupère le noeud de la position courante du joueur.
    noeud = mt.node.get(pos)
    # On remplace le noeud courant par du verre par défaut.
    mt.node.set(noeud, 'default:glass')
    # On met à jour la position en se décalant de 1 mètre.
    pos['x'] += 1

Exercice 2. Construire un “tronc d’arbre” en s’arrêtant au sol

  1. Créer un nouveau fichier de programme nommé exercice2.py.
  2. Copier-coller dedans le code à compléter ci-dessous.
    import miney
    mt = miney.Minetest()
    mon_joueur = mt.player[0]
    mon_joueur.fly = 5
    pos = mon_joueur.position
    noeud = mt.node.get(pos)
    # Tant que le noeud courant est de l'air
    while noeud[...] == ...:
        # On remplace le noeud courant par du bois de pin
        mt.node.set(noeud, ...)
        # On descend d'un mètre.
        pos[...] -= ...
        # Le neud courant est mis-à-jour : il correspond à la nouvelle position.
        noeud = mt.node.get(...)
    
  3. Compléter le programme précédent afin de faire construire au personnage une un tronc (une ligne verticale) commençant à la position courante du joueur et descendant jusqu’à toucher le sol. Les noeuds seront du type “bois de pin” (pine tree en anglais) . Consulter la liste des noeuds principaux à cette adresse. Identifier le nom du noeud (en anglais Itemstring, littéralement la chaîne de caractères désignnat l’élément).
  4. Dans Minetest déplcer votre personnage dans une zone dégagée et le positionner à quelques dizaines de mètre d’altitude par rapport au sol.
  5. Exécuter le programme précédent.
Correction
import miney
mt = miney.Minetest()
mon_joueur = mt.player[0]
mon_joueur.fly = 5
pos = mon_joueur.position
noeud = mt.node.get(pos)
# Tant que le noeud courant est de l'air
while noeud['name'] == 'air':
    # On remplace le noeud courant par du bois de pin
    mt.node.set(noeud, 'default:pine_tree')
    # On descend d'un mètre.
    pos['y'] -= 1
    # Le neud courant est mis-à-jour : il correspond à la nouvelle position.
    noeud = mt.node.get(pos)

Phase 3. Conception du module en respectant sa spécification

Le but du module est de fournir un ensemble de fonctions permettant de construire un ensemble d’arbres disposés selon une trame carré de maille de taille arbitraire.

On se limitera au départ à un seul modèle d’arbre. Pour cela on peut s’inspirer de modèles trouvés en ligne. Les arbres doivent respecter deux contraintes :

  • ils doivent respecter le relief de la carte (leur tronc doit commencer au niveau du sol)
  • ils ne doivent pas remplacer les bâtiments présents sur la carte. On pourra par exemple définir une liste de nature de noeud qu’il ne faut pas remplacer.

Dernière contrainte, il faut pouvoir annuler une construction précédente. Il faut donc que la liste des noeuds qui seront modifiés soient enregistrée avant toute modification de la carte.

L’une des fonctions pourra par exemple créer une liste de tuples de la forme suivante :

[
    (pos0, 'air', 'default:glass'),
    (pos1, 'air', 'default:dirt'),
    ...
]
où chaque tuple contient dans l’ordre trois informations :

  • la position (type dict dont les clés sont x, y et z) ;
  • la nature du noeud avant modification (par exemple 'air') ;
  • la nature du noeud après modification (par exemple 'default:glass')

Ainsi avec ces informations, il est possible de construire puis d’annuler la construction précédente en cas d’erreur.

Pour mettre en commun le code, créer et se partager un projet replit.

Commencer par écrire la spécification de chaque fonction en partant des plus simples. Coder puis tester ensuite progressivement chaque fonction.

Avant de commencer à coder, il est sans doute nécessaire de faire un brainstorming et de présenter graphiquement l’ensemble des fonctions qui seront utiles. Pour cela, utiliser par exemple l’outil MindMeister.

Au cours du codage, attention à bien docummmenter chaque fonction et commenter abondamment votre code pour qu’il soit facilement lisible par un programmeur ou une programmeuse qui découvre votre projet (ou le redécouvre c’est-à-dire vous dans quelques mois !).