La Bibliothèque de Neverwinter Nights
Aide et informations diverses sur Neverwinter Nights ainsi que D&D3.
La date/heure actuelle est 28/11/2024 21:41:32


  Page 1 sur 1 ¤

Voir le sujet précédent ¤ Voir le sujet suivant 
Auteur Message
Baldurien
L'homme qui chutait sur le macadam
Inscrit le: 12 Sep 2002
Messages: 14066
Localisation: Quadran Alpha
Répondre en citant
Posté le : 20/11/2005 02:30:55 Sujet du message : Qu'est ce qui lui manque à votre avis?

Suite à un message que j'ai écris (tant bien que mal) sur les forums Bioware - après l'avoir perdu suite à une mauvaise manip, et après avoir été copieusement *emmerdé* par les BioBoard pour des URL trop longues (...)), je m'interroge sur les évolutions du NWScript que vous - scripteurs - aimeriez voir?

Parmi ces évolutions (que j'aimerai voir), on peut trouver les tableaux, une réelle classification des objets, une syntaxe objet, de la javadoc, des itérateurs, une fonction de debug (print), et des événements ne faisant pas nécessairement appel à une fonction main situé dans un script.

Pour ce qui est d'ajouter votre missing list (liste des trucs qui manquent) je vous renvoie aux commentaires de nouvelle, où en vous trouverez les descriptions de ma missing list.


_________________
#nwnights-fr @ irc.darkmyst.org TitanQuest-FR
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web du posteur Ignorer l'utilisateur
 
Baldurien
L'homme qui chutait sur le macadam
Inscrit le: 12 Sep 2002
Messages: 14066
Localisation: Quadran Alpha
Répondre en citant
Posté le : 20/11/2005 03:23:15 Sujet du message :

Commençons par la classification des objets :

Dans NWN, on a plusieurs types d'objets, à savoir (liste non exhaustive) :

Module
Area (zone)
Creature
Placeable
Waypoint
Camera
Player

On peut classer ces objets tels que :

Module
- Contient des Area
- Contient des PlaceableObject : Creature, Placeable, Waypoint
Area
- Contient des PlaceableObject (le nom n'est pas très bon étant donné les objets Placeable)
Waypoint

Placeable

Dans NWN, on n'a affaire qu'à un seul type d'objet pour désigner plein de choses différentes. Pourquoi ne pas justement créer des types spécifiques permettant de rendre moins ambiguüe les choses?

Puis la syntaxe objets :

Vous manipulez les structures (struct {}) du jeu par l'opérateur '.'. La syntaxe objet, c'est pareil ! Donc, par exemple, on aurait area.addCreature(Creature c) qui nous permettrait d'ajouter une créature dans une zone. Simple non?

Avec cette syntaxe, ce qu'il faut c'est des setters et getters.

Il y a près de 1000 fonctions de base qui font tout et n'importe quoi. Y a une fonction pour chopper une carac, et y a 6 caracs : donc *pouf* on a 6 constantes, et une fonction, que l'on applique sur un objet qui doit être une créature. Mais attendez là ??? Qu'est ce qui m'affirme qu'un objet est une créature? Moi? ah oui... Mais c'est pas à moi de gérer ça : c'est au compilateur de me dire tu t'es trompé!

Rien que la syntaxe objet permettrait de réduire de beaucoup les écritures et rendrait beaucoup plus clair le code.

Un exemple? Prenez un script actuel et transformez le avec la syntaxe objet.

-> en sus, il faut des setter (définisseurs) et des getters (accesseurs). Ex tout bête:

Code :
Creature c = getCreature(1);
c.charisma = 3;
print c.charisma;


Ce qui est beau ici, c'est que derrière le compilateur va réécrire le code tel que :
Code :
setCharisma(c, 3);
print getCharisma(c);


Mais au final pas besoin d'appeler une fonction, le compilateur se démerdra tout seul (c'est un peu le but : on jette toutes les lourdeurs sur le compilateur)

Bien sûr, pour déplacer un objet d'un point de là où il est vers un autre point, ça fonctionnerait comme ça :

c.moveTo(waypointQuelconque);

(noter que je ne met pas wp, ou un quelconque préfixe aux noms de variable, c'est lourd.)

Tableaux

Trop utile pour être oublié! Un tableau c'est quoi? C'est un ensemble contigu et fini d'éléments de même type. Un exemple tout bête :

Code :
Waypoint[][] chess = new Waypoint[10][10];


Crée une matrice de Waypoint de 10x10 permettant par exemple de représenter un jeu d'échec. C'est un exemple mal fait, mais c'est l'idée.

Ce qui est merveilleux? Hé bien : vous pouvez itérer là dessus ! Et pouf :

Code :
for ( i = 0; i < chess.length; i++ )
  for ( j = 0; j < chess[i].length; j++ )
    print chess[i][j];


Si vous ne voyez pas d'applications, je suis sûr que d'autres vous en trouveront.

Et maintenant, le fin du fin : pourquoi pas des Map? Les Map c'est un objet de base des langages orientés objets. Ils permettent d'associer à une clef une valeur.

Exemple tout bête : vous voulez associer à une liste de créatures, une série de Waypoint.

Code :
Map<Creature, Waypoint> m = new Map<Creature, Waypoint>();

m.put(c1, w1);
...
m.put(cN, wN);


Et si vous voulez trouver le waypoint de destination associé à la créature, il vous suffit de faire un simple :

Code :
m.get(c1)


Et inclure les Map étant lourd, je propose de faire ça :

Waypoint[Creature]

Signifiant que les Waypoint sont indexés par des Creature plutôt que par des entiers.

Et mieux encore : ce tableau est extensible. Quand y a plus de place, y a de la place! (ie: si jamais on ajoute un élément et que le tableau est pas assez grand, on le ragrandit).

Ce qui implique les itérateurs

Etant donné ces maps, comment bien parcourir ces tableaux spéciaux dont on peut pas deviner les clefs? Réponse : avec foreach.

Ex:
Code :
/**
 * parcours d'un tableau de créature indexé par des entiers
 * mieux: si jamais c'est une liste d'élément (un objet
 * interne au jeu par exemple), on peut la parcourir ainsi
 * de manière [b]transparente[/b]
 */
foreach ( Creature c in tableauDeCreature )
  ;
/**
 * Idem, en déclarant implicitement deux variables c et p
 */
foreach ( tableauDeCreature as c => p )
  ;


c contient ici la créature (qui joue le rôle de clef), et p la position (qui joue le rôle de valeur).

Y a cependant un autre truc chiant dans NWN :

Code :
object o = getFirstObjectInArea();
while ( getIsValidObject(o) ) {
  destroyObject(o);
  o = getNextObjectInArea();
}


Ce code parcourt tous les objets de la zone (et on connaît pas leur type, yahoo) et les détruit. Ca ça marche, c'est génial hein.

Mais ajoutez donc des objets et vous obtiendrez une boucle infinie. C'est normal : NWN utilise une liste d'objets, et ajoute les objets en fin de la liste. Une solution consisterai à ajouter les objets en début de liste, mais hélas : cela implique d'utiliser une liste chaînée (ajout au début de liste en temps constant) tandis qu'ajouter en fin permet d'avoir une liste d'objets utilisant un tableau de références. Bien optimisé, ça peut être mieux que la liste d'objet, mais l'ajout au début est plus long car il faut décaler tous les autres objets.

Donc on ajoute en fin.

Donc on ne finit jamais la boucle puisque getNextObjectInArea renvoie toujours un objet. La boucle s'arrête que quand le jeu a bien planté.

A ça, je propose les itérateurs comme en Java (ceci dit c'est un design pattern de base).

Code :
for ( Iterator it = area.iterator(); it.hasNext(); ) {
  PlaceableObject o = it.next();
  if ( o isa Placeable )
    o.remove();
}


Ce que ça fait? Ca crée un objet Iterator en demandant à area de le créer, puis ça parcourt les éléments de la zone en nous assurant que la boucle soit fini (eg: une copie locale avec un champ indiquant le dernier élément de la liste d'objet de la zone).

Comme un zone contient différents types d'objets, on doit d'abord vérifier si l'objet n'est pas un Placeable pour le supprimer (c'est mon exemple).

Ici :
it.hasNext() renvoie vrai ou faux si on a fini d'itérer
it.next() renvoie l'objet courant et avance le pointeur interne (équivalent du getNext de tantôt)
it.remove() détruit l'objet courant avant l'appel de next()

C'est puissant, c'est magnifique!

Et mieux, puisqu'à priori on ne voudra pas tout le temps supprimer un objet, on peut même oser ça :

Code :
foreach ( PlaceableObject o in area )
  ;


Ca permet d'éviter d'écrire des choses trop longues, etc.

Mais un autre truc qui manque, c'est de quoi afficher facilement du texte dans la console, et puis faire des IntToStr(i) ça reste agaçant quant on sait que "a" + 6 en Java ne nécessite pas de faire "a" + IntToStr(6).

Je propose une nouvelle instruction : print.

Elle peut être désactivé si le mode debug est désactivé, et elle ne fait qu'afficher du texte dans la console.

ex:
Code :
Creature c = getCreature();
print 3, "3", c;
// affiche le nombre 3, la chaîne 3, et la créature (oui!)


On peut transformer en chaîne un objet, c'est à dire obtenir quelque chose de plus lisible qu'un tag. Le print a pour seul avantage d'afficher dans la console le texte. Pas besoin de faire un AssignAction(talkTo(...)).

Et puis tiens, OBJECT_SELF, OBJECT_INVALID, TRUE et FALSE sont pas terribles...

Je propose de renommer OBJECT_SELF en self, qui est de type Object (ça dépend le contexte). Faire Creature c = self devrait provoquer une erreur si c n'est pas une créature. Une erreur sévère finissant directement le script et affichant dans la console la fonction qui a provoqué l'erreur.

OBJECT_SELF est par contre moche : on vous a dit que les constantes devait être en majuscules... oui mais OBJECT_SELF c'est pas une constante.

OBJECT_INVALID est une constante, mais null serait plus approprié. null pour dire "y pas d'objets ici, il existe pas".

Et enfin TRUE et FALSE sont mis en vert dans l'éditeur de script. Pourquoi? Parce qu'ils sont pris en compte comme des mots clefs, pas des constantes. Ils méritent donc d'être écrit en minuscule : true et false.

Pour presque finir, les événements

Les événements c'est bien, mais c'est un fichier par événement. Vous trouvez pas ça lourd vous? Ce que je veux c'est pouvoir choisir la fonction qui va gérer l'événement et ne pas avoir 10 fichiers pour une créature alors que c'est une créature unique, et que que j'aimerai bien avoir tout ce qui la concerne au même endroit sans m'amuser à nommer les scripts de manière farfelues.

Et puis ça serait bien de jarter toutes les méthodes associées aux événements pour utiliser ce que le NWScript connaît : une structure (ou des paramètres) donnant par défaut les objets ayant provoqués l'événements.

Genre :

areaOnEnter(Creature c);

c est entré dans la zone, rien de bien compliqué, non?

Et derrière pas de getEnteringObject.

Et finalement, les commentaires de fonction/variables

Un truc qui est moche dans le NWScript c'est les commentaires de base et surtout la façon dont ils sont écrits : ça utilise les commentaires sur une ligne (//) comme si les commentaires multilignes (/*..*/) n'existaient pas, et pire : les gens font souvent de l'ASCII Art pensant qu'un script doit avoir des images.

Ce que je veux, c'est qu'il y ait une vraie syntaxe pour documenter les éléments. Cette syntaxe éxiste déjà : c'est la Javadoc.

Comme ça :

Code :
/**
 * Crée X objets
 * @param x le nombre d'objets à créer
 * @return retourne false en cas d'erreur (si x < 1, ou x > 5)
 */
bool creerXObjets(int x);


Et pas les commentaires imbiffables :

Code :
// Crée X objets
// false en cas d'erreur (si x < 1, ou x > 5)
bool creerXObjets(int x);


Voilà.

Bien sûr, c'est normal que je sois chiant sur ce point : j'ai connu d'autres langages que le NWScript, et je sais que ce que je propose va en partie apporter un mieux.

(mais encore faut il que les devs répondent autrement que "on n'en a pas besoin" et qu'ils y réfléchissent)
_________________
#nwnights-fr @ irc.darkmyst.org TitanQuest-FR
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web du posteur Ignorer l'utilisateur
 
Athanor salamander
Légende vivante
Inscrit le: 01 Avr 2003
Messages: 306
Localisation: Ecole du Script
Répondre en citant
Posté le : 21/11/2005 15:40:53 Sujet du message :

Ce qu'il manque dans le NWscript c'est surtout l'ouverture du controle vers les objects utilisés :
Pour expliquer ce que je veux dire par là on va y aller tout doux :
Aujourd'hui dans NWScript pour récupérer une valeur ou en assigner une à un object, le langage t'ouvre des méthodes, du genre Get qqchose et Set machin chose. Elles permettent la manipulation de certaines propriétés, mais ça reste hyper protégé et hyper privé.
En fait ça revient un peu au même que ce que tu décris dans ton post Baldurien au niveau technique, mais ce qui serait bien c'est d'avoir un accès aux objects bien plus vaste, à savoir une grosse modification de ceux ci :
Monstres : modifier les caracs, les dons, les sorts en direct, modifier leur apparence, leur nom etc... Avoir accès à l'animation en cours également, à son attaque, etc...
PC : idem, mais y avoir aussi des événements, pouvoir ajouter des events précis à un joueur.
Zones : Avoir accès à sa ResRef. Il faudrait aussi qu'une zone puisse écouter. (Event OnConversation, OnPerceived etc...)
Rencontre : Ajouter et supprimer des créatures à l'object rencontre, pouvoir positionner des points de rencontre, et avoir un événement d'avant déclenchement.
Plaçable : Leur donner une propriété de déplacement similaire aux créatures, afin de donner des effets aux décors. Aujourd'hui un plaçable est déplaçable mais cette gestion est différence que celle des créatures parce que gérables avec l'axe des Z. Il faudrait également qu'ils puissent être déplaçables de la même façon. Exemple, une maison qui s'enfonce, des éboulis de pierre etc... Qu'ils puissent écouter (pour des mots de passe par exemple)
Effects : Gérer les effets intégralement (mis à part les visus) par script. Ainsi au lieu d'un effet directement géré en interne, qu'on puisse avoir directement une librairie de fonction permettant réellement de gérer et d'utiliser l'object Effect. Par ailleurs donner à chaque effet une signature (à savoir, l'effet en cours, qui l'a lancé, depuis quand il est sur cet object, est il néfaste, est il redondant avec un autre effet etc...) :
NWScript :
effect eMyEffect(){

// script de l'effet

}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.

Aujourd'hui la fonction effect existe mais ne sert à rien, sinon à linker linker et linker.

En fait, pour finir, mis à part certaines choses qu'il manque énormément au NWScript, très bien expliqués par Baldurien, ce qui handicape le plus ce langage qui est mine de rien assez convivale, c'est la trop haute protection des object qu'il gère, et la simplicité trop gênante de ces mêmes objects. Un plaçable est trop plaçable donc inerte, un effect est trop rigide, un monstre n'est pas assez modellable etc...
_________________
Atha, Artisan Scripteur.
meet the most beautiful woman in the world
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé MSN Messenger Ignorer l'utilisateur
 
Montrer les messages depuis :
Page 1 sur 1 ¤


Vous ne pouvez pas poster de nouveaux sujets dans ce forum
Vous ne pouvez pas répondre aux sujets dans ce forum
Vous ne pouvez pas éditer vos messages dans ce forum
Vous ne pouvez pas supprimer vos messages dans ce forum
Vous ne pouvez pas voter dans les sondages de ce forum


Sauter vers:
FAQ | Rechercher | Liste des Membres | Groupes d'utilisateurs | S'enregistrer | Profil | Se connecter pour vérifier ses messages privés | Connexion
Powered by phpBB 2.* [m] © 2001, 2002 phpBB Group
Theme rewritten in beautiful XHTML code by Baldurien.
Thème "La Bibliothèque de Neverwinter" crée par Kruger
Traduction par : phpBB-fr.com
Page generated in 39.513ms