Documentation Ark : Système d'entités

Next Previous Contents

## 3. Système d'entités

## 3.1 Utilité de ce système

Dans Ark, chaque objet réel ou fictif du monde est représenté par une entité. Tous les décors (arbre, maisons) sont des entités, ainsi que les personnages (joueurs, PNJs) et les accessoires. De plus les entités peuvent être des objets fictifs, inexistants, qui ne servent en réalité que d'auxiliaire pour le moteur de jeu. Il s'agira du point de départ d'un joueur sur une carte ; ou encore d'un "bouton" invisible qui déclenche une action quand on le traverse : par exemple on peut penser à une diode laser qui déclenche l'ouverture d'une porte.

Donc pour résumer : tout est une entité. Quel intêret donc d'un tel système ? Une interface abstraite et unifiée pour l'accès aux fonctions du moteur permet la création d'un seul ensemble de fonction, qui pourra indifféremment servir à gérer tout les types d'objets imaginables sur une carte : par exemple, si on faisait une différence entre "accessoire" et "auxiliaire", il faudrait gérer plusieurs types de collision entre le joueur et les objets du monde, alors qu'avec un unique type d'entité, il suffit de gérer la collision entité/entité pour traiter tout les cas possibles.

On a vu que pour le moteur, le système d'entité est positif, en limitant le nombre de cas différents à traiter. Qu'en est-il lorsqu'on se penche sur la programmation des réactions des objets ? En effet, pour programmer les réactions, il faut pouvoir accéder aux propriétés de l'entité, et on voit bien mal comment avoir une unique liste de données qui permettrait de prendre en compte tout les types d'entités : en effet il faudrait un nombre énorme de données pour chaque entité, et la plupart de ces données resterait inutilisée. Pourquoi une entité correspondant à un être humain aurait-elle besoin de données concernant les propriétés d'une arme.

On doit donc définir différentes classes d'entités, et chacune de ces classe aura ses paramètres qui lui seront propres. Pour une arme, on aura puissance, usure, etc, pour un homme ce sera points de vie, intelligence, force... On sent déja une nette amélioration, mais il manque "quelque chose". En effet, prenons deux armes : une épée et un arc. Elles partagent des propriétés communes : usure et puissance. Mais elles ont aussi chacune d'autres propriétés : par exemple pour l'arc, il pourra s'agir de la portée, ou du nombre de flèches, etc.

Il est alors logique de penser à une hiérarchie de classes. Tout en haut, il y a la classe entité, avec les paramètres communs à toutes les autres classes : nom, modèle 3D, etc. Puis des classes spécialisées d'entité : accessoire, décors et personnages. Chacune de ces classes possède d'autre classes spécialisées, qui précisent encore la fonction de l'objet et ajoutent des propriétés : parmi les accessoires, on trouve les armes, les outils, les clés, etc. Les clés sont des accessoires qui sont eux-mêmes des entités : ainsi chaque objet du monde dérive d'entité (c'est à dire qu'il partage les caractéristiques communes d'entité), mais peut aussi avoir des caractéristiques propres au type qu'il représente.

Cette organisation en classes qui possèdent des propriétés, et qui peuvent dériver de superclasses, qui regroupent les propriétés communes à plusieurs classes, est une des bases de la programmation orientée objet qu'on appelle héritage

## 3.2 Définition de types d'entités

Toutes les classes d'entités utilisées dans un jeu sont enregistrées dans un unique fichier, généralement dans {game}/scripts/entities.def. Chaque déclaration de classe commence par le nom de la classe, éventuellement des informations d'héritage, puis un bloc entre accolades où sont définies toutes les propriétés de la classe. La définition se termine par un point-virgule. Par exemple :

            Accessoire inherits Objet
            {
            };

Ce morceau de code définit une classe Accessoire qui hérite des propriétés de la classe Objet sans lui en ajouter de nouvelles. La classe objet pourrait être définie de cette façon :

            Objet
            {
                    STRING model
                    {
                            desc = "Modèle 3D";
                            default = "";
                    }
            };

Cette fois-ci on définit une classe Objet qui n'a pas de superclasse et qui possède uniquement une propriété de type 'chaîne de caractère' (STRING) appelée 'model', avec la description et la valeur par défaut données. Les différents types de propriété sont :

- STRING, une chaine de caractère (un morceau de texte).
- INTEGER, une valeur entière (par exemple 1, 10, 1256).
- SCALAR, une valeur réelle (par exemple 1.0, 12.125)
- VECTOR3, un vecteur, qui désigne une position absolue ou relative dans le monde. C'est un trio de valeurs réelles, correspondants respectivement aux coordonnée X, Y et Z du vecteur (par exemple {1.0, 12.125, 1.0}).

Des informations additionnelles concernant le type de donnée contenu par une propriété peuvent être données dans la partie 'desc' de la déclaration d'une propriété. Celle-ci sert uniquement pour l'éditeur d'entité inclus dans l'éditeur de quêtes, pour donner une idée de l'utilité de la propriété ; si la description commence par un morceau de texte entouré par des crochets [], ce morceau de texte sera analysé et servira à déterminer plus précisément le type de donnée contenu, et à proposer des outils de séléction plus pertinents (outil de sélection de fichier, etc). Par exemple :

            Objet
            {
                    STRING model
                    {
                            desc = "[model]Modèle 3D";
                            default = "";
                    }
            };

Le texte "[model]" signifie que la propriété 'model' correspond au nom d'un modèle 3D. Ainsi l'éditeur d'entité proposera un outil de sélection de modèle 3D quand cette propriété sera éditée. Les valeurs supportées sont :

- class : la chaîne de caractère contiendra le nom d'une classe.
- model : la chaîne de caractère contiendra le nom d'un modèle.
- enum/E1/E2/.../En : la chaîne de caractère contiendra une valeur parmi E1, E2, ..., En.
- bool: l'entier donné ne pourra que contenir qu'une valeur 0, qui signifie 'faux' ou 1, qui signifie 'vrai'. Dans l'éditeur d'entité, il s'agira d'une case à cocher.
- range/min/max : l'entier donné sera compris entre min et max (au sens large).

## 3.3 Modèles d'entités

Les modèles d'entités sont généralement déclarés dans le fichier {game}/scripts/entities.tmpl ; ils faut faire attention à ne pas confondre modèle d'entité et modèle 3D. Un modèle d'entité est une entité de référence, qui peut être utilisé comme base pour un objet dans une quête. Ainsi tout les objets courants auront des modèles : par exemple, quand on veux rajouter une Dague daphy dans une quête, on peut utiliser le modèle Dague daphy, qui aura déja toutes les propriétés d'une dague daphy (usure, puissance, poid, modèle 3D, etc.), quitte à en modifier certaines si on veut faire un Unique (arme qui ne se trouve qu'à un seul endroit).

Le fichier entity.tmpl définit tous les modèles disponibles à l'échelle du monde. Sa syntaxe est assez simple à comprendre :

            template Gueux implements Personne
            {
                    name = "Igor le Gueux";
                    model = "{game}/data/models/peon.3ds?2.0";
                    lifepoints = 120;
                    strength = 25;
                    agility = 20;
                    knowledge = 15;
            }

Ce morceau de code définit un modèle d'entité appelé Gueux, de la classe Personne ; on peut assigner des valeurs à chacune des propriétés, dans un bloc entre accolades qui suit la ligne déclarant le modèle. Plusieurs modèles peuvent bien sûr se suivre dans un même fichier...

## 3.4 Déclaration d'entités dans une quête

La liste des entités d'une quête se trouve généralement dans le fichier entities.lst de cette quête. La syntaxe est identique à celle du fichier de définition de modèles à la différence que le mot-clé template ne précède pas la déclaration de l'entité. Par exemple, on pourra avoir :

            implements Personne, uses Gueux
            {
                    name = "Bix le Gueux";
                    shortname = "Personne0";
                    lifepoints = 240;
            }

            implements Accessoire
            {
                    name = "L'Epée du diable";
                    model = "{models}/sword.mdl";
                    shortname = "Sword0";
                    usury = 100;
            }

Le premier bloc définit un Gueux, appelé 'Bix le Gueux' , qui utilise le modèle Gueux, en changant toutefois le nombre de points de vie (quoique gueux, Bix est très robuste !). Le deuxième bloc définit un Accessoire, appelé 'L'Epée du diable', avec ses caractéristiques propres ; cette fois-ci on n'utilise pas de modèle, le valeurs par défaut de la classe seront donc utilisées. La valeur d'une propriété est déterminée dans cet ordre là : on utilise d'abord la valeur spécifique de l'entité (celle définie dans entity.tmpl), s'il n'y en a pas on utilise la valeur du modèle, puis en dernier recours la valeur par défaut de la propriété.

Next Previous Contents