Bienvenue

Jeu vidéo

Save the Valley

C++17SFML 2.6CMakeSimplex Noise

Jeu sandbox 2D développé de zéro en C++ avec une architecture de moteur maison. Génération procédurale d'un monde infini, système de combat à plusieurs armes, IA ennemie à machines à états et rendu optimisé par chunks, le tout sans moteur de jeu.

Le problème

Le but n'a jamais été de livrer un produit fini, mais de comprendre ce qu'un moteur de jeu abstrait réellement. La plupart des développeurs utilisent Unity ou Unreal et ne touchent jamais directement à une boucle de rendu, à un système d'entités ou à un pipeline de collisions. Je voulais construire ces briques moi-même en C++ pour me forger un vrai modèle mental des systèmes bas niveau que je tiendrais sinon pour acquis.

Décisions clés

Pas de moteur de jeu : du C++ pur avec SFML comme seule dépendance

SFML gère la fenêtre, les événements d'entrée et le rendu des textures, et rien d'autre. Pas de graphe de scène, pas de moteur physique, pas de pipeline d'assets. Écrire à la main la boucle de mise à jour des entités, le partitionnement spatial et le système de caméra m'a obligé à penser budgets de performance et organisation mémoire d'une manière qu'un moteur aurait complètement masquée.

Monde découpé en chunks plutôt que chargé en entier

Un monde infini ne tient pas en mémoire d'un seul bloc. Il est divisé en chunks de taille fixe, et seuls ceux proches du joueur sont actifs. Quand le joueur franchit un seuil, les chunks de l'arrière sont sérialisés et déchargés, et ceux de l'avant sont chargés ou générés. L'utilisation mémoire reste ainsi constante, quelle que soit la distance parcourue.

Machine à états finis pour l'IA ennemie plutôt que des arbres de comportement

J'ai commencé un prototype avec une bibliothèque d'arbres de comportement, mais c'était surdimensionné pour trois états : Idle, Wandering et Hunting. Une FSM aux transitions explicites tenait dans un seul fichier, se déboguait facilement en affichant l'état courant et restait assez rapide pour faire tourner des centaines d'ennemis sans toucher au temps de frame. La complexité ne se justifie que si le problème l'exige.

Bruit Simplex plutôt que Perlin pour générer le terrain

Le bruit de Perlin produit à certaines fréquences des artefacts visibles alignés sur les axes, et le terrain prend un aspect quadrillé. Le bruit Simplex est invariant par rotation et son gradient est plus isotrope, ce qui donne des contours de terrain plus naturels sans post-traitement. Le coût de calcul est comparable.

Résultat

Le projet m'a pris trois mois de soirées et de week-ends. À la fin, j'avais un monde infini fonctionnel, un système de combat à trois armes et une IA ennemie qui poursuivait le joueur d'un chunk à l'autre. Surtout, j'en ai tiré une compréhension concrète des pipelines de rendu, du partitionnement spatial et de l'architecture d'une boucle de jeu, que j'applique à chaque projet en temps réel.

Fonctionnalités

Monde procédural

  • Chunks infinis avec chargement et déchargement dynamiques
  • Plusieurs biomes avec leur propre génération de terrain
  • Autotiling pour des transitions douces entre types de tuiles
  • Objets avec collision : arbres, rochers, structures

Système de combat

  • Épée, hache et marteau avec hitboxes dynamiques
  • Points de vie, dégâts et frames d'invulnérabilité temporaire
  • Animations d'attaque, de dégâts et de mort

IA ennemie

  • Machine à états : Idle → Wandering → Hunting
  • Détection du joueur à portée
  • Poursuite avec évitement d'obstacles

Rendu

  • Rendu par chunks (seuls les chunks visibles sont dessinés)
  • Par couches : terrain / objets / entités
  • Caméra fluide + mode de débogage des collisions

Démo

Génération du monde

Combat

Travaillons ensemble