VSCode Extension: Achievements
- POK
- 2024-2025
- temps 2
- dev
- vscode
- Loïck Goupil-Hallay
Développement d'une extension permettant de débloquer des succès en fonction de l'utilisation de VSCode.
POK avancé
Achievements
Introduction
Toujours dans l'optique de créer le meilleur environnement de développement possible, je me suis demandé ce qui permet au développeur d'être le plus heureux quand il travaille. C'est alors que je me suis rappelé que la majorité des développeurs a un passif (ou un présent) de joueur de jeux vidéo. Un système de succès pousse les joueurs à continuer de jouer et les récompense pour leur temps passé sur le jeu. Cela booste la motivation et la satisfaction du joueur.
Et puis Qui n'a jamais rêvé de terminer VSCode ? C'est pourquoi j'ai décidé de développer une extension pour VSCode permettant de débloquer des achievements en fonction de l'utilisation de l'éditeur.
Il existe déjà deux extensions de ce type sur le marché, mais elles ne sont pas complètes du tout et ne sont plus maintenues. J'ai donc décidé de développer la mienne, qui sera plus complète et plus à jour.
Fonctionnement
L'extension Achievements
fonctionne de manière assez simple. Le but est de ne pas impacter les performances de l'éditeur et de pouvoir fonctionner hors ligne.
Workflow
Le workflow de l'extension est le suivant:
- L'intégrité de la base de données est vérifiée à chaque démarrage de l'extension. S'il y a un problème, elle est patchée comme il faut.
- Des listeners sont mis en place pour écouter les événements de l'éditeur (ouverture de fichier, sauvegarde, etc.).
- Chaque listener déclenche l'augmentation d'un ou plusieurs critère de progression.
- Lorsqu'une progression est augmentée, on vérifie si elle permet de débloquer un succès.
- Si un succès est débloqué, on le notifie à l'utilisateur.
- A tout moment, l'utilisateur peut aller consulter la liste des succès débloqués / en cours sur la Webview de l'extension.
Webview
L'extension dispose d'une Webview qui permet à l'utilisateur de consulter la liste des succès débloqués et en cours. Cela permet de garder un historique des succès débloqués et de voir les succès restants à débloquer.
Commandes
L'extension ajoute des commandes custom à la palette VSCode à vscode:
achievements.enable
: Active / désactive l'extensionachievements.settings
: Ouvre la configuration de l'extensionachievements.show
: Ouvre la Webview des succès
Il s'agit de raccourcis pour les actions les plus courantes.
Settings
L'extension dispose de quelques paramètres de configuration:
achievements.enabled
: Active / désactive l'extensionachievements.logLevel
: Niveau de log de l'extensionachievements.logDirectory
: Dossier de stockage des logsachievements.username
: Nom d'utilisateur à afficher dans la Webviewachievements.listeners.debug
: Active / désactive les listeners pour les évènements de type debug / breakpointachievements.listeners.extensions
: Active / désactive les listeners pour les évènements de type extension, thèmeachievements.listeners.files
: Active / désactive les listeners pour les évènements de type ouverture de fichier, sauvegardeachievements.listeners.git
: Active / désactive les listeners pour les évènements de type gitachievements.listeners.tabs
: Active / désactive les listeners pour les évènements de type ouverture de tabachievements.listeners.tasks
: Active / désactive les listeners pour les évènements de type tâches VSCodeachievements.listeners.time
: Active / désactive les listeners pour les évènements de type temps passé
Base de données
- J'utilise une base de données SQLite pour stocker les succès, leurs conditions de déblocage, leur état, la date de complétion, et tout un tas de propriétés.
- Je stocke aussi la progression de chaque critère pour débloquer les succès. Cela me permet de savoir si un succès est débloqué ou non.
- Il y a de nombreux achievements qui ne peuvent se débloquer que si certains autres sont débloqués. Pour cela, j'utilise une table qui stocke les dépendances entre les succès.
- Enfin, je stocke les versions de la base de données pour pouvoir mettre à jour les tables en fonction de la version de l'extension. (C'est utile pour les mises à jour qui vont nécessiter des migrations de bases de données).
erDiagram SchemaVersion { int id PK int version datetime applied_at } Achievement { int id PK string title string icon string category string group string description int tier int exp int hidden int repeatable boolean achieved datetime achievedAt } AchievementLabel { int achievement_id FK string label } AchievementCriteria { int id PK int achievement_id FK int progression_id FK string required_value string type string comparison_operator } AchievementRequirement { int achievement_id FK int requirement_id FK } Progression { int id PK string name string type string value } DailySession { int id PK string date int duration } Achievement ||--o{ AchievementLabel : "has" Achievement ||--|{ AchievementCriteria : "has" Achievement ||--o{ AchievementRequirement : "has" AchievementRequirement ||--|| Achievement : "references" AchievementCriteria }|--|{ Progression : "references"
Développement
VSCode fonctionne grâce à Electron, ce qui signifie qu'il fonctionne exactement comme un site web. Le développement des extensions se fait donc en JavaScript / TypeScript. J'ai choisi d'utiliser TypeScript pour mon extension car il permet de s'assurer que le code est correctement typé avant de l'exécuter. Cela permet de réduire les erreurs et de gagner du temps.
Le développement se centre sur l'optimisation des performances et la réduction de l'impact sur l'éditeur. Cela passe par deux choses essentielles:
- l'optimisation SQL pour réduire le nombre de requêtes et traiter les données le plus rapidement possible
- la gestion des listeners pour ne pas surcharger l'éditeur avec des événements inutiles ou dupliquer les fonctionnalités déjà existantes
Dépendances
Pour mon extension, j'ai utilisé les dépendances suivantes :
- Développement
npm
pour le management des dépendancesesbuild
pour le bundling du code (le lint, la compilation de TypeScript)eslint
pour l'analyse statique du codetypescript
pour le typage du code
- Run
vscode
pour l'API de VSCodebetter-sqlite3
pour la base de donnéesreact
pour l'interface utilisateurstyled-components
pour les styles de l'interface des composants react
Post-mortem
La documentation de l'API de VSCode concernant les webviews est TRES MAUVAISE, contrairement à ce qu'on pourrait croire, il est très difficile de trouver des exemples concrets pour réaliser des actions relativement peu complexes. On dirait que les développeurs de VSCode ont oublié de documenter leur propre API.
Au niveau de l'extensibilité, qui est un des arguments principaux de VSCode, c'est un peu la déception. Il est très difficile de faire des choses qui sortent de l'ordinaire concernant les webviews. Je suis obligé de passer par de multiples hacks pour arriver à mes fins (afficher des images ?????). La communication extension <-> webview est un véritable calvaire avec 0 documentation mis à par un exemple miteux. Le framework n'est vraiment pas bon pour le développement de vues personnalisées et complexes (ils déconseillent aux utilisateurs de développer des webviews pour des raisons de performances mais ce n'est pas une raison pour ne pas prendre en charge leur ajout).
Le bundle des vues n'est pas prévu par défaut par VSCode, c'est une catastrophe pour packager ses images / icones / css / js. Il faut tout mettre à la main dans le bundle, ce qui est une perte de temps et d'énergie pour des choses qui devraient être automatisées.
Planning
Date | Heures passées | Indications |
---|---|---|
Mercredi 12/11 | 3H | Etablissement du projet, création du premier modèle de base de données |
Jeudi 13/11 | 4H | Création des premiers succès (1200), standardisation de l'attribution des points, des difficultés,... |
Samedi 15/11 | 3H | Création de la webview et communication extension <-> webview |
Samedi 01/12 | 6H | Migration / Optimisation SQL pour minimiser l'impact sur les performances |
Samedi 08/12 | 4H | Création des listeners d'events et tests d'intégration |