Développement de Jeux avec Odin et Raylib : Réécrire un Tower Defense
Réécrivez un jeu de tower defense de Lua/Love2D vers Odin et Raylib. Découvrez les avantages d'Odin pour la programmation de jeux et les fonctionnalités de Raylib pour un développement 2D efficace.
Introduction
Odin est présenté comme une alternative à C pour la programmation de jeux, offrant haute performance et développement orienté données. Raylib est une bibliothèque simple et facile à utiliser pour la programmation de jeux vidéo, complétant Odin pour le développement de jeux 2D.
Précis de configuration

| Élément | Version / Lien |
|---|---|
| Langage principal | Odin |
| Langage comparatif | Lua |
| Librairie principale | Raylib |
| Librairie comparative | Love2D |
| APIs requises | JSON (pour les données de niveau) |
Autres librairies via vendor |
SDL3, EGL, Lua, STB, X11, ENet, Curl, GGPO, GLFW, libc, SDL2, WASM, WGPU, ZLIB, Box2D, CGLTF, OpenGL, Darwin, NanoVG, Vulkan, OpenCL, DirectX, MicroUI, Windows |
Guide étape par étape
Étape 1 — Le Contexte : Un Jeu de Tower Defense en Lua/Love2D
Le projet initial était un jeu de tower defense développé en sept jours avec des amis, utilisant Lua et Love2D. Cette expérience a permis de construire un système d'interface utilisateur robuste et un système d'animation. Le développeur a noté que la gestion d'une base de code Lua de 70 000 à 80 000 lignes devenait complexe.
Étape 2 — La Transition vers Odin pour le Développement de Jeux
Face aux défis de Lua, l'idée de réécrire le jeu dans un langage plus adapté à la programmation de jeux, comme Odin, est apparue. Odin est perçu comme un langage plus propice à la programmation de jeux, offrant une meilleure gestion des grands projets.
Étape 3 — Utilisation de Raylib pour le Rendu et les Contrôles

Raylib est une bibliothèque simple et facile à utiliser, offrant des interfaces claires pour la gestion des contrôles, du framerate et du dessin, ce qui simplifie grandement le développement 2D. Elle permet une manipulation aisée des textures, y compris le dessin sur texture et la gestion des rectangles source/destination pour le scaling et le flipping.
// game/cell.odin
cell_draw :: proc(cell: ^Cell) {
assert(cell.sprite != nil, "cell_draw: cell.sprite = nil"); // Vérifie que le sprite de la cellule n'est pas nul
overhang := f32(assets.OVERDRAW_SIZE - assets.TEXTURE_SIZE); // Calcul de l'overhang pour le dessin
x_offset := f32(cell.col * C.GRID_PX_SIZE) - overhang; // Calcul du décalage X
if cell.reverse {
x_offset = f32(assets.OVERDRAW_SIZE - assets.TEXTURE_SIZE) * 2; // Ajustement si la cellule est inversée
}
// Note de l'éditeur : La ligne suivante est fragmentée dans la transcription et semble incomplète.
// height := f32(cell.row * C.GRID_PX_SIZE) - overhang - height; // Calcul de la hauteur
sprite := cell.sprite; // Récupération du sprite de la cellule
rl.SetTextureFilter(sprite.texture, .POINT); // Définition du filtre de texture
dest_w := f32(assets.OVERDRAW_SIZE); // Largeur de destination
if cell.reverse {
dest_w = f32(assets.OVERDRAW_SIZE * 2); // Ajustement si la cellule est inversée
}
dest_h := f32(assets.OVERDRAW_SIZE); // Hauteur de destination
// Note de l'éditeur : 'dest.reverse' n'est pas défini dans le contexte fourni.
// if dest.reverse {
// dest_h = -dest_h; // Inversion de la hauteur si la destination est inversée
// }
rl.DrawTexturePro(
sprite.texture,
sprite.rect,
// Note de l'éditeur : 'pos.y', 'width' ne sont pas définis dans le contexte fourni.
// rl.Rectangle{x_offset, pos.y, width, dest_h}, // Rectangle de destination
rl.Rectangle{x_offset, 0, dest_w, dest_h}, // Exemple de rectangle de destination ajusté
rl.Vector2{0, 0}, // Origine
0, // Rotation
rl.WHITE // Couleur de teinte
);
}
Étape 4 — Gestion des Dépendances avec le Système vendor d'Odin
Odin simplifie l'intégration de bibliothèques externes grâce à son système vendor. Il permet d'importer facilement des bibliothèques comme Raylib, SDL3, Lua, Curl, etc., qui sont pré-intégrées dans l'environnement Odin, facilitant un démarrage rapide du projet sans gestion complexe des dépendances.
package game
import "assets"
import "constants"
import "random"
import rl "vendor:raylib"; // Importe la bibliothèque Raylib via le système vendor
// Note de l'éditeur : La transcription montre une liste de dossiers sous /usr/lib/odin/vendor/, indiquant la disponibilité de nombreuses bibliothèques via ce mécanisme.
// ... (autres imports et définitions)
Étape 5 — Surcharge de Fonctions Explicite et Utilisation du Mot-clé using

Odin offre une surcharge de fonctions explicite, où toutes les versions d'une fonction surchargée doivent être listées. Le mot-clé using dans les structs permet d'accéder directement aux champs d'une struct imbriquée, améliorant la lisibilité et la commodité du code. Par exemple, une fonction attendant un type Coord peut accepter un type Cell si Cell utilise Coord.
// game/cell.odin
Coord :: struct {
row: int,
col: int,
}
Cell :: struct {
using coords: Coord, // Permet d'accéder directement à 'row' et 'col' de Coord via Cell
is_placeable: bool,
is_path: bool,
reverse: bool,
sprite: ^assets.Sprite,
}
cell_index :: proc { // Surcharge de fonction pour cell_index
cell_coord_to_index,
cell_row_col_to_index,
}
cell_index_to_coord :: #force_inline proc(index: int) -> Coord {
r, c := cell_index_to_row_col(index);
return Coord{row = r, col = c};
}
cell_coord_to_index :: #force_inline proc(coord: Coord) -> int {
return cell_row_col_to_index(coord.row, coord.col);
}
cell_row_col_to_index :: #force_inline proc(row: int, col: int) -> int {
return row * C.GRID_COLS + col;
}
cell_coord_from_position :: #force_inline proc(pos: rl.Vector2) -> Coord {
x := pos.x / C.GRID_PX_SIZE;
y := pos.y / C.GRID_PX_SIZE;
return Coord{col = cast(int)x, row = cast(int)y};
}
// Exemple d'utilisation (extrait de debug.odin)
// for c in data.cells {
// idx := cell_index(c); // 'c' est une Cell, mais grâce à 'using coords: Coord' et la surcharge, Odin peut l'utiliser comme un Coord
// // ...
// }
Tableaux comparatifs
Odin vs Lua pour le développement de jeux
| Critère | Lua (avec Love2D) | Odin (avec Raylib) |
|---|---|---|
| Facilité de démarrage (2D) | Très facile | Très facile (grâce à vendor et Raylib) |
| Gestion des dépendances | Peut devenir complexe avec beaucoup de lignes de code | Simplifiée via le système vendor |
| Performance | Moins performant pour de grandes bases de code | Haute performance, langage compilé |
| Robustesse du code | Moins robuste pour de grands projets | Plus robuste, typage distinct, orienté données |
| Plaisir de programmer | Diminue avec la taille du projet | Retrouvé grâce à la conception du langage |
⚠️ Erreurs fréquentes et pièges
- Gestion de code Lua volumineux : Lua, bien que simple au début, peut devenir difficile à maintenir et à débugger avec des dizaines de milliers de lignes de code.
- Solution : Envisager des langages plus structurés et performants comme Odin pour des projets de plus grande envergure. Le développeur a ressenti une perte de passion en gérant un code Lua trop grand.
- Dépendances complexes : Dans d'autres langages, l'intégration de bibliothèques tierces peut être fastidieuse et source de problèmes.
- Solution : Utiliser le système
vendord'Odin qui pré-intègre de nombreuses bibliothèques populaires, simplifiant leur utilisation et réduisant les problèmes de dépendances.
- Solution : Utiliser le système
- Code généré par IA de mauvaise qualité : Les outils d'IA peuvent produire du code qui nécessite une refactorisation importante ou qui est incorrect, même pour des tâches simples.
- Solution : Utiliser l'IA comme un copilote pour des tâches spécifiques (ex: lecture de JSON, conversion de données) mais toujours vérifier, comprendre et refactoriser le code généré pour s'assurer de sa qualité et de son intégration.
Glossaire
Odin : Un langage de programmation généraliste, orienté données, conçu pour la haute performance et le développement logiciel sain, souvent présenté comme une alternative à C pour la programmation de jeux.
Raylib : Une bibliothèque simple et facile à utiliser pour la programmation de jeux vidéo, offrant des fonctionnalités pour le dessin 2D/3D, la gestion des entrées et l'audio.
Surcharge de fonctions explicite : Une fonctionnalité d'Odin qui permet de définir plusieurs fonctions avec le même nom, à condition de lister explicitement toutes les versions surchargées, offrant clarté et flexibilité.
Points clés à retenir
- Odin est une alternative performante et agréable à C pour le développement de jeux, particulièrement pour les projets 2D.
- Le système
vendord'Odin simplifie l'intégration de nombreuses bibliothèques externes comme Raylib et Box2D. - Raylib offre des interfaces intuitives pour le rendu graphique, la gestion des textures (rectangles source/destination) et les contrôles.
- Les fonctionnalités d'Odin comme la surcharge de fonctions explicite et le mot-clé
usingaméliorent la lisibilité et la commodité du code. - L'intégration de l'IA avec Odin est fluide pour des tâches spécifiques, bien que le code généré nécessite toujours une validation humaine.
- Le projet vise à retrouver le plaisir de coder en explorant de nouveaux langages et en se concentrant sur la création personnelle.
Ressources
- Documentation officielle d'Odin : [Note de l'éditeur : lien non fourni dans la transcription, mais le site web est affiché à 01:49]
- Documentation officielle de Raylib : [Note de l'éditeur : lien non fourni dans la transcription, mais le site web est affiché à 03:06]