Le wiki de la création de jeux

La base de données étendue

Une des choses les plus limitées de RPG Maker est la base de données. En effet, on ne peut pas créer de nouveau champ ni de nouvelle table. On ne peut qu’ajouter des enregistrements dans les structures déjà prévues. RME implémente un système de base de données extensible à souhait.

Un peu de terminologie

Pour être sur la même longueur d’onde, voici un résumé du vocabulaire que l’on utilisera dans cette section.

A titre d’exemple, voici à quoi correspondent ces mots dans la base de données de RPG Maker :

Base de données de RPG Maker

Nous pouvons désormais mettre des mots plus précis sur la limite de RPG Maker : alors que l’on peut ajouter autant d’enregistrements que l’on veut, on ne peut pas altérer la structure d’une table.

Deux nouvelles bases de données

Deux bases de données ont été ajoutées à RME. La première est un complément de la base de données native, elle permet de décrire des données statiques qui ne changeront pas en cours de jeu. La seconde est une base de données dynamique, qui est vide au départ, se remplit au cours du jeu et est mémorisée lors des sauvegardes.

Typiquement, la base de données statique permet de décrire des nouvelles structures de données et la base de données dynamique des inventaires. La procédure de création de table est presque identique pour les deux bases de données.

Création d’une table

Les champs de la base de données sont typés. Cela veut dire qu’à l’exécution du jeu, la base de données vérifie leur validité (dans la mesure du possible).

En général, la création d’une table se fait dans l’éditeur de script. Vous pouvez créer un champ de script libre en dessous de RME dans lequel vous écrirez vos tables. La description d’une table est structurée ainsi :

class NomDeLaTable < TypeDeLaTable
  pk type :champ_cle_primaire
  type :un_autre_champ
  type :un_autre_champ
end

type est à remplacer par le type désiré. Par exemple, pour décrire une quête dans la base de données statique, on pourrait proposer ce schéma :

class Quest < Static::Table
    pk integer :id
    string :name
    string :description
    integer :gold
    integer :exp
end

La clé primaire, signalée par pk, correspond à l’index d’un enregistrement. Elle doit toujours être définie et être unique à cet enregistrement. On peut s’en servir pour référencer l’enregistrement depuis une autre table.

Créons par exemple une table dynamique pour marquer la quête comme terminée en cours de jeu :

class Game_Quest < Dynamic::Table
    pk integer :quest_id
    boolean :finished
end

Ici, la clé primaire serait l’ID de la quête représentée dans la table statique.

Chaque champ doit impérativement être typé pour qu’à chaque insertion il y ait une conversion dans le bon type (si possible).

Survol des types possibles

Les types sont une petite coquetterie (mise en place par éthique et morale !) permettant plus de fiabilité dans la réalisation d’une base de données. Avant de se lancer dans la création d’une table, il est donc nécessaire de bien réfléchir à son système de type !

Nom Description Autres noms
integer Nombre entier. int natural fixnum
float Nombre à virgule. double real numeric
string Texte. text raw
boolean Booléen (true ou false). bool switch
poly Donnée RGSS/Ruby quelconque. polymorphic script rgss

Types issus du RGSS

Les types du RGSS sont un peu particuliers car ils stockent juste l’ID d’un élément de la base de données originale. Lorsqu’on les appelle, ils donnent l’objet Ruby s’y référant. C’est un outil pratique pour faire des relations avec la base de données de RPG Maker de manière propre.

Nom Description
actor Héros
class Classe de personnage
item Objet
weapon Arme
armor Armure
enemy Ennemi
troop Groupe d’ennemis
state Etat
animation Animation
tileset Tileset
mapinfo Infos de la carte
map Carte

Ces types permettent de faciliter l’accès à des données statiques de RPG Maker. Ils ne peuvent pas être utilisés comme des clés primaires.

Les listes

Il arrive parfois qu’un champ doive être une liste de données. Il existe pour cela un constructeur de type qui prend une liste.

list :type, :nom
list :integer, :family_members_ids # Exemple

Il est possible d’imbriquer les listes pour faire des listes de listes de listes d’entiers par exemple. Mais si vous ne souhaitez pas vous embêter avec de la déduction de type, vous pouvez utiliser le type polymorphe.

Connaitre le schéma d’une table

En jeu, il est possible de connaître le schéma d’une table sans devoir le lire dans l’éditeur de script. Il suffit d’écrire Nom_de_la_table.schema.

Insertion dans la base de données dynamique

Les insertions dans la base de données dynamique peuvent être effectuées dans un script ou un appel de script.

Nom_de_la_table.insert(valeur_du_champ1, champ2, etc)

Notez qu’aucun champ ne peut être ommis.

Fonctionnement de la base de données statique

Lancer le jeu depuis l’éditeur génèrera les fichiers de la base de données dans le dossier Database/tables créé à la racine du projet. Une table statique est un fichier csv, donc modifiable via Excel ou l’éditeur de code de votre choix. Chaque ligne correspond à un nouvel enregistrement. L’exécution depuis l’éditeur crée aussi un fichier Data/StaticDB.rvdata2 qui comprend une version compilée de la base de données statique. De ce fait, lorsque le jeu est fini, le répertoire Database peut être supprimé.

(Le répertoire backups va être présenté dans la section suivante, le répertoire views, lui, contient des données de configuration des tables et ne doit pas être modifié ou utilisé).

Modification d’une table

Si on change la structure d’une table, par exemple en ajoutant un nouveau champ alors que le fichier csv avait déjà été construit, la table est vidée. En effet, le script ne peut pas deviner comment adapter la modification de la table.

Cependant, pas de panique ! Une version de la table avant la modification est stockée dans le répertoire Database/backups avec un identifiant unique. On peut donc retrouver le contenu d’une table malgré une modification de sa structure.

Suppression d’une table

Si une table est supprimée, son fichier csv est là aussi déplacé dans Database/backups. Normalement, on ne perd jamais de table sans le désirer.

Accès aux champs

Maintenant que vous savez renseigner des enregistrements dans une table, nous allons voir comment récupérer leurs données en jeu. Pour cette partie, une connaissance des tableaux est préférable mais pas obligatoire.

On peut connaitre le nombre d’enregistrements d’une table avec la méthode count. Par exemple, pour obtenir le nombre de quêtes enregistrées : Quest.count.

Pour accéder à un enregistrement en particulier, on écrit Table[clé primaire]. Par exemple, Quest[1] pourra renvoyer l’objet Quest suivant :

(1, "Tuer les slimes", "Il faut tuer 10 slimes", 100, 200)

Pour récupérer un champ précis uniquement, il suffit d’ajouter son nom à la suite. Pour obtenir le nom de la quête 1, on écrit Quest[1].name.

On peut aussi obtenir tous les objets Quest d’un coup avec Quest.all.

Itération sur une table

Il est possible d’effectuer une itération sur une table en suivant ce modèle :

Table.each{|pk, record| vos commandes ici}

Voici un exemple affichant le nom de toutes les quêtes via leur clé primaire :

Quest.each do |pk, record|
	p "#{pk} -> #{record.name}"
end

L’itération sur une table fonctionne comme l’itération sur un tableau, où l’index est la clé primaire pk de l’enregistrement record.

Cas particuliers du mode dynamique

Rappelons que la base de données dynamique peut être modifiée au cours du jeu. Il est possible d’ajouter, de modifier et de supprimer des enregistrements. La procédure d’insertion est la même que pour la base de données statique mais elle peut être utilisée partout et sauvegarde les changements.

Pour modifier un champ, il suffit d’accéder au champ et de lui attribuer une nouvelle valeur.

Game_Quest[10].finished = true

Table.delete(pk) supprime l’enregistrement correspondant à la clé primaire donnée.

Table.delete_if{|pk, record| prédicat} supprime tous les enregistrements correspondant au prédicat. Par exemple, pour supprimer toutes les quêtes dans Game_Quest dont l’or rapporté est supérieur à 10 :

Game_Quest.delete_if{|pk, rec| Quest[rec.quest_id].gold > 10}

Il s’agit d’une requête composée qui va interroger la table statique Quest.

Mapping de la base de données standard

Afin de profiter de cette agréable syntaxe pour la base de données standard de RPG Maker, RME construit plusieurs tables statiques préfixées de VXACE_.

On peut appliquer à ces tables les mêmes fonctions qu’aux tables statiques. Pour connaitre leurs champs, rendez-vous dans la documentation du module RPG de RPG Maker VX Ace. Les données sont typées, y compris les listes.

La table VXACE_MAP est un peu particulière car elle fusionne les informations de MapInfo et Map. Il est donc possible d’accéder aux champs des deux structures via un seul enregistrement. Par exemple, obtenir les notes d’une carte revient à écrire : VXACE_MAP[ID].note.

Tables internes

Il existe des tables internes utilisées par RME. Elles commencent par un I, par exemple IColor pour les profils de couleur. Si par mégarde vous en supprimez une, ce n’est pas grave : ces fichiers sont régénérés s’ils n’existent pas.

Conclusion

Cet outil peut être assez compliqué à prendre en main pour un débutant. Il est recommandé d’avoir une base en programmation avec Ruby. Cependant, il peut faciliter la création de systèmes. L’équipe RME s’en sert en interne pour plusieurs choses, notamment l’afficheur de textes !


Dernière mise à jour le 29 décembre 2020