Molko's Adventure

Posted on Tue 14 January 2020 in code, annonce

Suite à mon dernier avis de décès, je souhaite aujourd'hui vous parler du développement de mon prochain jeu : Molko's Adventure.

Avant-propos

Fan de la première heure des jeux vidéo rétros et des anciens Final Fantasy, j'ai toujours rêvé de faire le mien il y a une vingtaine d'années. D'ailleurs, c'est bien en manipulant RPG Maker 95, 2000 et 2003 après avoir joué à un sur un CD d'un magazine que l'envie de programmer m'est venue.

RPG Maker est un outil de création de jeu propriétaire basé sur des assistants. On ne programme pas directement mais on utilise des actions prédéfinies comme :

  • Faire clignoter l'écran ;
  • Téléporter le joueur ;
  • Lancer un combat.

Il existe tout de même des variables, conditions et boucles mais elles se font aussi via ces assistants. Pour commencer je pense que c'est un bon outil pour les débutants et donner l'envie de créer. En revanche ces versions étaient largement limitées. Certaines versions récentes utilisent Ruby comme langage d'extension.

Histoire

Sans vouloir trop en dire afin de ne pas raconter la fin, je vais essayer de fournir assez d'éléments pour donner envie de jouer ou contribuer. Pour la suite du billet, j'utiliserai l'abréviation MA pour des raisons de simplicité.

Molko's Adventure se déroule dans une époque entre médiéval et monde moderne. Il existe donc de la machinerie, des aéronefs mais pas de smartphones.

Gameplay

Le système de jeu est assez similaire aux anciens Final Fantasy. Le joueur se déplace sur des cartes en 2D et interagit avec des PNJ. Les combats se déclenchent aléatoirement en marchant.

Le joueur incarne jusqu'à quatre personnages en même temps. Ces personnages ne se choisissent pas et arrivent au fur et à mesure du jeu. En revanche, il est possible de les personnaliser en leur attribuant des classes spéciales.

Carte du monde

Le joueur peut se déplacer sur des cartes standard et la carte du monde. Cette dernière a une particularité différente : les objets y sont plus petit pour laisser plus de place à la carte. Ainsi, notre personnage a une taille plus grande que les villages qu'il croise.

Exemple avec Golden Sun :

golden-sun

Système d'évolution

Contrairement à beaucoup de RPG, le joueur ne possède pas de niveau global. Ce mode se rapproche plutôt du système de Final Fantasy II ou chaque aptitude pouvait évoluer. Cette flexibilité permet de faire évoluer son personnage comme on le désire.

En revanche, Final Fantasy II a souffert de ce choix en raison de son implémentation. Ainsi, il n'est pas rare que des joueurs se tapaient - littéralement - eux-mêmes afin d'augmenter les aptitudes désirées. Ce comportement est totalement contre productif.

Le fonctionnement à venir dans le jeu est un système d'attribution par pourcentage.

Prenons par exemples les aptitudes suivantes :

  • Vie : le nombre de point de vie ;
  • Magie : le nombre de point de magie pour les sorts ;
  • Force : capacité à infliger des dégâts physiques ;
  • Défense : réduire les dégâts subits ;
  • Agilité : augmente la préparation à l'attaque et les esquives physiques ;
  • Chance : permet d'obtenir plus d'objets rares après un combat ;

Le joueur pourra décider sur quelle aptitude attribuer l'expérience gagnée en combat. Voici une table de possibilité.

L'implémentation n'est pas encore définie, mais imaginons un système à trois points (entre 0 et 5) à attribuer. Nous donnons deux points par aptitude par défaut ce qui donne douze points à attribuer. Voici une table de répartition que l'on pourrait imaginer par type de joueur :

Agressif Peureux Polyvalent Setzer
Vie o ooooo ooo oo
Magie o oo ooo oo
Force ooooo o oo o
Défense o oooo oo
Agilité oooo o ooo
Chance o oooo

Système de classes

Un des systèmes que j'apprécie beaucoup est celui de Final Fantasy V. Ce jeu offre des classes (appelés “jobs” dans la version anglophone) qui permettent de faire évoluer les personnages comme bon vous semble. De plus, cette flexibilité offre un choix de combinaisons puissante pour le joueur.

Exemple de combinaison puissante : X-Fight + 2 armes. Attaque 8 fois pendant un tour. Du bonheur.

Combats

Le système de combat se déroule sur une grille isométrique (la taille est en fonction de la carte) où les joueurs et les ennemis se déplacent pour se frapper.

Ce mode de combat est assez similaire à Dofus ou Final Fantasy Tactics. En revanche contrairement à Dofus, chaque personnage que le joueur incarne se prépare en parallèle. Cela signifie que le joueur choisit des actions à effectuer par personnages à la suite mais que ces derniers peuvent être tous prêts en même temps selon leur temps de « préparation ».

Exemple de combat style Dofus :

dofus

Design

Comme tout bon nostalgique des jeux rétros vous avez du deviner, le jeu sera entièrement en Pixel Art ! En effet, lorsque ce type de design est bien réalisé il peut-être très élégant.

Voici une image en pixel art que je trouve particulièrement bien réussie :

pixel-art

À noter toutefois, le jeu ne sera pas développé dans une résolution antédiluvienne qu'étaient nos vieilles consoles (à savoir 320x240). À priori la résolution de choix sera du 720p mais ce n'est pas encore gravé dans le marbre.

Architecture et implémentation

Tiled

L'outil pour dessiner et créer les cartes est tiled. C'est un choix assez logique devant la notoriété de cet outil.

Les cartes sont toutefois converties dans un fichier texte maison afin de limiter les dépendances aux fichier XML/JSON que tiled créé. Cela simplifie aussi le code de chargement car nous exportons que les données qui nous intéresse.

title|Maison de Molko
height|200
width|400
tilewidth|32
tileheight|32
layer|background
0
0
0
0
... abrégé pour la simplicité
layer|foreground
0
1
1
... abrégé pour la simplicité

Bibliothèques et outils

Les bibliothèques utilisées sont :

Pour construire le projet il suffit simplement de :

  • GCC, Clang, MinGW-w64
  • POSIX make.

Pourquoi ai-je décidé de le coder en C ?

Chose surprenante, le jeu est entièrement codé en C, C18 pour être plus précis. En tant que grand messager du C++ moderne, j'ai décidé de repartir sur mon ancien langage de prédilection pour plusieurs raisons.

Faut il réellement être fou pour coder un jeu en C ? Je pense que non du moment que l'on ne s'acharne pas à tout surcomplexifier. D'ailleurs, Cryptic Studios est une entreprise connue pour développer leurs jeux en C pur.

Orienté objet et jeu

Une question qui survient souvent sur les forums de débutants est l'architecture des données d'un jeu vidéo.

Le paradigme orienté objet ne se marie pas toujours avec excellence lorsqu'il s'agit de créer les données.

Prenons un cas simple :

  • Une classe Ennemi, classe de base des ennemis ;
  • Une classe Dragon (hérite de Ennemi), vole et ne peut être touché que par des attaque magiques ou aériennes ;
  • Une classe Sirène (hérite de Ennemi), peut se cacher dans l'eau pour ne pas être touchée.

bad-oo

Comment implémenter une créature type « Dragon Sirène » ? Avec un héritage multiple ? Mon dieu non.

Pour réaliser ce genre de concept, on part plutôt sur des systèmes à composants. Beaucoup de jeux vidéo utilisent le concept ECS où chaque objet est une entité simple à laquelle nous ajoutons des composants annexes pour l'étendre.

Ainsi, pour illustrer notre cas précédent nous pourrions implémenter plutôt :

  • Aptitude de vol
  • Aptitude d'immersion

Ensuite, il nous reste plus qu'à attacher ces deux aptitudes à nos créatures et le jeu s'occupe du reste. Et pour cela, pas besoin d'orienté objet.

correct-ecs

Simplicité

Il existait un article nommé “Make games, not engines”. Il est vrai qu'en tant que développeurs nous avons parfois la fâcheuse tendance à vouloir :

  • Tout complexifier ;
  • Tout rendre générique ;
  • Toujours inventer ;
  • Et Jean Passe.

Pour MA, je me force justement à rester simple, minimaliste et à ne pas développer un moteur avant un jeu. Cela se ressent dans le code et il reste facile à maintenir. En effet, il contient beaucoup d'éléments fixes, statiques et complètement liés à ce type de jeu précisément.

Cependant, cela ne veut pas dire qu'il faut développer n'importe comment. Les principes mêmes comme DRY, SRP et KISS doivent rester. Ainsi, le code qui gère l'ouverture de la fenêtre ne doit faire que ça.

Conclusion : le code bien que faiblement flexible pourra facilement être réutilisé pour une suite ou un jeu similaire, les données et scénario du jeu étant dissociés du fonctionnement.

Procédural

La manière de développer un jeu vidéo est globalement souvent la même. Pour faire simple :

main-loop

Encore une fois, ce principe même n'a pas besoin d'un langage complexe et haut niveau. De simples fonctions suffisent.

Orienté données et fonctions

Comme présenté plusieurs fois au dessus, un jeu vidéo est surtout construit autour d'un nombre élevée de données. Ensuite, le jeu est capable de les gérer de lui même. Évidemment, ce n'est pas suffisant puisque dans le cas d'un RPG il faudra aussi rajouter des actions spéciales liées aux PNJ.

Ce qui est uniquement en données :

  • Les cartes ;
  • Les animations ;
  • Les images, sprites et tilesets ;

Ce qui nécessite un mélange de données et d'actions :

  • Les objets ;
  • Les magies ;
  • L'IA des ennemis en combat ;
  • Les PNJs.

Note : listes non exhaustives.

Liens

Comme d'habitude, projet hébergé sur Mercurial et géré via Redmine.