Documentation de Torque 1.3.x
Transcription
Documentation de Torque 1.3.x
Documentation de Torque V1.3.x Documentation de Torque V1.3.x (Traduction DrQuid – 2006 – édition 1) Tous droits réservés © 2004 GarageGames.com, Inc. Torque Game Engine (TM) est une marque déposée de GarageGames.com, Inc. GarageGames est une marque déposée de GarageGames.com, Inc. Tous les noms de produits matériels et logiciels, les images, et termes sont soumis aux droits de leurs propriétaires, éditeurs, développeurs, distributeurs respectifs, où ils sont applicables. La version de cette documentation correspond à Torque 1.3. Lors de la traduction, il a été tenu compte, autant que possible, de la version 1.4. 1 / 223 Documentation de Torque V1.3.x Table des matières 1 Pour commencer...........................................................................................................................................5 1.1 Pour commencer...................................................................................................................................5 1.2 Base de développement.......................................................................................................................5 1.3 Script contre C++..................................................................................................................................5 1.4 Outils et éditeurs...................................................................................................................................6 1.5 Quoi faire maintenant ?.........................................................................................................................9 2 Création d'un jeu indépendant à succès avec Torque.................................................................................11 2.1 Aperçu.................................................................................................................................................11 2.2 Étape 1 : soyez réaliste.......................................................................................................................12 2.3 Étape 2 : identifiez les technologies nécessaires................................................................................13 2.4 Étape 3 : acquisition de technologies existantes.................................................................................15 2.5 Étape 4 : construction d'un prototype grossier et rapide.....................................................................17 2.6 Étape 5 : Itérez !..................................................................................................................................21 2.7 Conclusion..........................................................................................................................................27 3 Les éditeurs de Torque................................................................................................................................28 3.1 Introduction à l'éditeur GUI..................................................................................................................28 3.1.1 Qu'est-ce qu'une GUI ?...............................................................................................................28 3.1.2 Exploration de l'éditeur GUI........................................................................................................29 3.1.3 Bases de l'éditeur GUI................................................................................................................32 3.1.4 Création d'un nouveau dialogue..................................................................................................39 3.1.5 Mettre tout ensemble..................................................................................................................43 3.1.6 En résumé...................................................................................................................................45 3.2 Introduction à l'éditeur de mission.......................................................................................................46 3.2.1 Aperçu des éditeurs de Torque....................................................................................................46 3.2.2 Les outils de l'éditeur de mission.................................................................................................46 4 Torque script...............................................................................................................................................88 4.1 Concepts et terminologies de TorqueScript.........................................................................................88 4.1.1 Script ou pas script ?..................................................................................................................88 4.1.2 Fonctionnalités nécessaires........................................................................................................89 4.1.3 Que dire sur TorqueScript ?........................................................................................................90 4.1.4 La console et les scripts simples.................................................................................................90 4.2 Le langage de TorqueScript................................................................................................................91 4.2.1 Caractéristiques du langage.......................................................................................................91 4.2.2 Les variables...............................................................................................................................92 4.2.3 Les opérateurs............................................................................................................................96 4.2.4 Les commandes de contrôle.......................................................................................................96 4.2.5 Les fonctions...............................................................................................................................98 4.2.6 Les objets...................................................................................................................................99 4.2.7 Les packages............................................................................................................................103 4.2.8 Les espaces de nommage (namespace) .................................................................................106 4.2.9 Les datablocks (blocs de données ...........................................................................................107 4.3 Interface avec le moteur....................................................................................................................107 4.3.1 Terminologie..............................................................................................................................107 4.3.2 Matrice des problèmes/solutions d'interface du moteur.............................................................108 4.3.3 addField()..................................................................................................................................110 4.3.4 addFieldV()................................................................................................................................111 4.3.5 Type de classes Validator..........................................................................................................112 4.3.6 addNamedField() et addNamedFieldV()....................................................................................112 4.3.7 Macro Offset()...........................................................................................................................112 4.3.8 removeField()............................................................................................................................112 4.3.9 Con::addVariable.......................................................................................................................112 4.3.10 Con::removeVariable (obsolète)..............................................................................................113 4.3.11 Con::addCommand (obsolète).................................................................................................113 4.3.12 ConsoleMethod.......................................................................................................................113 4.3.13 ConsoleFunction.....................................................................................................................114 4.3.14 Fonctions supplémentaires d'interface du moteur...................................................................114 4.4 Retour sur les datablocks, les objets et les espaces de nommage...................................................115 2 / 223 Documentation de Torque V1.3.x 4.4.1 La connexion aux objets datablocks..........................................................................................115 4.4.2 Les espaces de nommage me donnent mal à la tête !..............................................................119 4.5 Résumé............................................................................................................................................123 5 Codage du moteur en C++........................................................................................................................125 5.1 Introduction.......................................................................................................................................125 5.1.1 Torque et la documentation du moteur......................................................................................125 5.1.2 Qu'ai je besoin de savoir ? .......................................................................................................125 5.1.3 Que dois-je faire si les documentations sont incomplètes.........................................................125 5.1.4 Crédits......................................................................................................................................126 5.2 Flux de contrôle de base ..................................................................................................................126 5.2.1 Introduction...............................................................................................................................126 5.3 Couche plate-forme...........................................................................................................................127 5.3.1 Aperçu.......................................................................................................................................127 5.3.2 Modèle d'événement.................................................................................................................127 5.3.3 Utilitaires de plate-forme...........................................................................................................127 5.3.4 Fonctionnalité réseau................................................................................................................128 5.3.5 Interface de jeu (GameInterface)..............................................................................................128 5.4 Console.............................................................................................................................................128 5.4.1 Aperçu.......................................................................................................................................128 5.4.2 Référence du langage console..................................................................................................128 5.4.3 Les fonctions.............................................................................................................................128 5.4.4 Les classes, objets et espaces de nommage............................................................................129 5.4.5 Les packages............................................................................................................................132 5.4.6 Les variables.............................................................................................................................132 5.4.7 Les tableaux..............................................................................................................................133 5.4.8 Les opérateurs spéciaux de chaîne..........................................................................................133 5.4.9 Le compilateur..........................................................................................................................133 5.4.10 Le débogueur..........................................................................................................................133 5.4.11 Interface avec le code C++......................................................................................................133 5.5 Simulation.........................................................................................................................................134 5.6 Fichiers, flux et gestionnaire de ressources......................................................................................136 5.6.1 Aperçu.......................................................................................................................................136 5.6.2 Chemins de recherche..............................................................................................................136 5.6.3 Fichiers Volume........................................................................................................................136 5.6.4 Ressource et ResourceObjets..................................................................................................136 5.7 Modèle d'entrée................................................................................................................................137 5.7.1 Aperçu.......................................................................................................................................137 5.7.2 Entrée plateforme......................................................................................................................137 5.7.3 Cartes d'actions........................................................................................................................137 5.7.4 Touches modificatrices..............................................................................................................137 5.8 Graphismes.......................................................................................................................................137 5.8.1 Aperçu.......................................................................................................................................137 5.8.2 Le gestionnaire de textures (Texture Manager).........................................................................138 5.8.3 Support des primitives...............................................................................................................138 5.8.4 Primitives de rendu...................................................................................................................138 5.8.5 Rendu 3D..................................................................................................................................138 5.9 L'interface graphique utilisateur (GUI)...............................................................................................138 5.9.1 Aperçu.......................................................................................................................................138 5.9.2 Traitement des événements d'entrée dans le système GUI......................................................139 5.9.3 Rendu des contrôles dans le système GUI...............................................................................139 5.9.4 Le système GUI et la Console..................................................................................................140 5.10 L'interface graphique utilisateur (GUI).............................................................................................140 5.10.1 Aperçu.....................................................................................................................................140 5.10.2 SceneGraph............................................................................................................................140 5.10.3 Terrain.....................................................................................................................................141 5.10.4 Interior.....................................................................................................................................141 5.10.5 3Space (TS)............................................................................................................................141 5.11 Le réseau........................................................................................................................................142 5.11.1 Aperçu.....................................................................................................................................142 3 / 223 Documentation de Torque V1.3.x 5.11.2 Couche de gestion de réseau de plate-forme..........................................................................143 5.11.3 Protocole de connexion...........................................................................................................144 Annexe A : Création du Torque Game Engine...............................................................................................148 A.1 Aperçu...............................................................................................................................................148 A.2 Création de Torque pour Windows....................................................................................................148 A.2.1 Préparation de votre système...................................................................................................148 A.2.2 Compilation du Torque Game Engine SDK avec le Microsoft Visual C++ .NET 2003 (7.1).......149 A.2.3 Compilation du Torque Game Engine SDK avec le Microsoft Visual C++ .NET 2002 (7.0).......151 A.2.4 Compilation du Torque Game Engine SDK avec le Microsoft Visual C++ 6.0...........................153 A.2.5 En résumé................................................................................................................................156 A.3 Création de Torque pour Mac OS X..................................................................................................156 A.3.1 Préparation de votre système...................................................................................................156 A.3.2 Compilation du Torque Game Engine SDK avec Xcode............................................................157 A.4 Création de Torque pour Linux..........................................................................................................157 A.4.1 Préparation de votre système...................................................................................................157 A.4.2 Compilation du Torque Game Engine SDK sur Linux et OpenBSD...........................................158 Annexe B : Utilisation de l'application Torque Demo.....................................................................................164 B.1 Aperçu..............................................................................................................................................164 B.2 Lancement de l'application...............................................................................................................164 B.3 Arguments de la ligne de commandes de Torque Demo...................................................................164 B.4 Raccourcis clavier............................................................................................................................165 B.5 Jeux et mods....................................................................................................................................166 B.6 Outils intégrés...................................................................................................................................166 B.6.1 L'éditeur de mission (Mission Editor)........................................................................................166 B.6.2 L'éditeur de GUI (GUI Editor)....................................................................................................166 B.6.3 L'outil de visualisation (Show Tool)...........................................................................................166 B.7 Arborescence des répertoires de l'application...................................................................................166 Annexe C Fonctions et commandes de la console Torque............................................................................168 C.1 Terminologie.....................................................................................................................................168 C.2 Mots clefs réservés..........................................................................................................................168 C.3 Opérateurs de script.........................................................................................................................168 C.4 Commandes et fonctions..................................................................................................................170 Annexe D Les Datablocks de Torque............................................................................................................172 D.1 SimDataBlock...................................................................................................................................172 D.2 GameBaseData................................................................................................................................172 D.3 ShapeBaseData...............................................................................................................................173 D.4 PlayerData........................................................................................................................................176 D.5 ItemData...........................................................................................................................................182 D.6 MissionMarkerData, CameraData, PathCameraData et StaticShapeData.......................................184 D.7 VehicleData......................................................................................................................................185 D.8 FlyingVehicleData.............................................................................................................................190 D.9 HoverVehicleData.............................................................................................................................192 D.10 WheeledVehicleData......................................................................................................................196 D.11 TriggerData.....................................................................................................................................197 D.12 ProjectileData.................................................................................................................................198 D.13 DebrisData.....................................................................................................................................200 D.14 SplashData.....................................................................................................................................204 D.15 LightningData.................................................................................................................................207 D.16 PrecipitationData............................................................................................................................208 D.17 ExplosionData................................................................................................................................209 D.18 ParticleEmitterNodeData et ParticleEmitterData.............................................................................216 D.19 ParticleData....................................................................................................................................220 D.20 WheeledVehicleTire et WheeledVehicleSpring...............................................................................223 4 / 223 Documentation de Torque V1.3.x 1 Pour commencer 1.1 Pour commencer OK, vous avez fait l'acquisition du Torque Game Engine (TGE) et êtes excité à l'idée de commencer à écrire votre jeu de tueurs ! Vous voulez savoir quoi faire maintenant... Bien, le TGE est un énorme moteur, et il y a plusieurs manières de l'utiliser. Une seule ne fait pas tout. Lisez, et vous apprendrez et utiliserez diverses fonctionnalités de TGE, et créerez le jeu que vous avez toujours souhaité créer, mais impossible jusqu'à maintenant. Dans ce chapitre, vous aurez un large aperçu du processus impliqué dans la création d'un jeu basé sur Torque. Nous allons voir brièvement comment obtenir le code source, examiner les meilleures façons d'écrire des jeux avec Torque, et jeter un coup d'œil aux outils pour développeurs de jeux pour créer des jeux avec le TGE. 1.2 Base de développement Il y a quelques bases sur le fonctionnement de Torque que vous devez comprendre avant de pouvoir continuer. Torque est très sophistiqué, employant des technologies de différents aspects de la science, des mathématiques et des techniques numériques. Le dernier code de Jarrod Roberson1 contient 2286 classes, 1493 fichiers, 20160 fonctions et 494990 lignes de code. Évidemment, apprendre la totalité de tout cela dans un temps court n'est pas possible. Heureusement, il n'est pas nécessaire de tout connaître sur Torque avant de commencer la construction d'un jeu, d'avoir du plaisir, et d'apprendre sur le moteur au fur et à mesure. Ceci est le point de départ. Au travers de cette brève introduction, nous vous indiquerons des sources pour vous aider à commencer le travail avec le TGE et obtenir des résultats indépendamment de vos connaissances ou compétences. Si vous connaissez déjà la programmation, l'utilisation d'un compilateur, l'utilisation d'un contrôleur de code source, et que vous ne pouvez pas attendre, jetez un coup d'œil au tutoriel de démarrage rapide créé par BurningRose Studios2. Le code source de TGE est distribué aux possesseurs du SDK3 via le téléchargement d'un programme d'installation. Celui-ci est téléchargeable via le lien fourni lorsque vous avez fait l'acquisition de Torque. Ensuite, lorsque des mises à jour du SDK sont disponibles, vous pouvez les télécharger à partir des liens proposés dans votre page My Account page. 1.3 Script contre C++ Les développements avec Torque supposent un certain niveau de connaissance avec les concepts de base de la programmation d'un ordinateur. Ces tutoriels ne sont pas conçus pour enseigner aux développeurs les bases du C++. Il y a, cependant, de nombreux excellents livres disponibles sur ce sujet pour ceux ayant besoin de se rafraîchir la mémoire. Bien que le moteur soit écrit en C++ et en assembleur, la majeure partie de votre jeu sera programmée en langage de script Torque (Torque Scripting Language) utilisé dans les fichiers avec l'extension .cs. Les avantages de l'utilisation d'un langage de script au lieu de tout coder en C++ sont : votre jeu n'a pas besoin d'être recompilé chaque fois que vous faites une modification ; il est plus ciblé ; langage de jeu de plus haut niveau que le C++ ; et vous n'avez pas besoin de vous inquiéter de la gestion de la mémoire. Une idée populaire fausse est que les scripts sont lents, ceci n'est plus nécessairement vrai. Torque Script est compilé en pseudocompilé avant son exécution et, il est étonnamment rapide. Tandis que le code C++ sera toujours le plus rapide, la flexibilité du script est supérieure pour la plupart des fonctions relatives aux jeux. Nous sentons que la clef du succès dans la programmation d'un jeu utilisant Torque est de comprendre 1 2 3 Développeur de Torque Membre de la communauté GarageGame SDK = Software Development Kit : kit de développement. C'est un ensemble d'outils permettant aux développeurs de créer des applications de type défini. 5 / 223 Documentation de Torque V1.3.x l'utilisation du langage de script. Ceci est décrit en détail dans le chapitre « Script ». Une fois que vous êtes conscients des capacités du langage de script de TGE, vous pouvez penser à ce que vous souhaitez réaliser en code C++. Généralement, nous essayons de coder autant que possible avec le langage de script, et de réaliser les routines rapides importantes en C++ qui pourront être appelées à partir du script. Les autres informations majeures sur l'édition des sources C++ peuvent être trouvées dans la section « Code » de la documentation. Il y a aussi de la documentation dans le code du moteur dans les commentaires. 1.4 Outils et éditeurs Un moteur de jeu complexe et moderne doit interagir avec plusieurs outils et éditeurs de tierce partie pour générer des données, des modèles, et des graphismes dans le jeu, et le TGE n'est pas différent. Ci-dessous se trouvent quelques outils que vous pourrez avoir besoin pour construire les éléments nécessaires à la création d'un jeu avec Torque. 1.4.1 Éditeurs de texte Pour éditer les fichiers de script, vous aurez besoin d'un éditeur de texte assez puissant. Il y a plusieurs options disponibles, mais GarageGames recommande d'utiliser jEdit. jEdit est un éditeur de texte basé sur Java avec quelques fonctionnalités puissantes, beaucoup vous seront utiles lors de l'édition de vos scripts pour Torque. Une des fonctionnalités les plus puissantes est ses plug-ins4 qui vous permettent de télécharger de nouveaux compléments sans avoir à quitter l'éditeur. jEdit est également gratuit et depuis qu'il est écrit en Java, il est multiplates-formes. • • jEdit Programmers Text Editor Complément TIDE pour les fonctions de navigation, et de débogage de Torquescript dans jEdit. 1.4.2 Compilateurs Pour éditer du code C++ et compiler le moteur, vous aurez besoin d'un compilateur approprié à votre système d'exploitation (OS). Les applications recommandées pour chaque OS sont listées ci-dessous. • • • Microsoft Windows : Microsoft Visual C++ 7.1 (.NET 2003) Mac OS X : Xcode Linux : Eclipse ou GCC La documentation sur la compilation sur Windows, Mac OS X et Linux est disponible. Les fichiers des projets pour chacun de ces compilateurs seront téléchargés dans le répertoire Torque racine lorsque vous installez le SDK du moteur. 1.4.3 Outils graphiques La création d'un jeu, qui est à la fois visuellement attractif et avec de bonnes performances, est un des plus grands défits de la conception d'un jeu. Torque vous permet de travailler avec différents éléments graphiques afin d'assurer des performances optimales tout en maintenant la qualité visuellement la plus élevée possible. Pour beaucoup de jeux, les éléments graphiques les plus importants sont les modèles 3D. Le TGE offre un support optimisé de haut niveau pour trois types différents de modèles 3D : les terrains, les intérieurs, et les formes détaillées. Chacun de ces types de modèles est créé de manière différente. • • 4 Un terrain est la base pour les grandes zones extérieures vues dans la plupart des jeux Torque. Le TGE représente les espaces ouverts en utilisant une grande carte pour déterminer l'élévation, et peut mélanger 6 textures ensemble sur la surface du terrain. Les terrains sont édités dans le jeu en utilisant l'éditeur de mission intégré (Mission Editor). Pour en apprendre plus sur cette zone, lisez le bref synopsis en dessous et référez-vous au chapitre « Éditeur de mission » dans cette documentation. Les intérieurs (interiors) définissent de grands objets, tels que les constructions, et les espaces dans lesquels les joueurs peuvent se promener. Ces intérieurs sont stockés dans un format Module externe venant se greffer sur le programme principal afin de lui apporter de nouvelles fonctionnalités (Wikipédia) 6 / 223 Documentation de Torque V1.3.x • appelé DIF, qui utilise la structure BSP (Binary Space Partition), similaire à ce qu'on trouve dans n'importe quel moteur de jeu basé sur Quake. Les DIF peuvent être créés en utilisant QuArK ou n'importe quel autre programme d'édition du format .map Valve 220. Pour une brève introduction sur la construction des intérieurs, voyez plus loin, ou sautez directement au chapitre « QuArk » de cette documentation. Les formes DTS sont des objets plus petits et plus détaillés que ceux que vous pouvez construire avec le format DIF. Par exemple, cela inclut les modèles des joueurs, les armes, les véhicules, et d'autres objets détaillés comme les arbres. Ce format permet des détails incroyables et des possibilités d'animations complexes, mais simplifie les collisions à une boîte d'encadrement et à quelques brosses convexes. Les objets DTS peuvent être exportés à partir d'une large variété de modeleurs tels que Blender, Maya, et d'autres. Regardez plus loin pour un aperçu de la description de chacun de ces outils. Les textures pour ces objets 3D peuvent être créées au format BMP, GIF, JPEG et PNG. Les canaux alpha sont supportés pour les textures PNG sur des formes DTS. Il y a beaucoup de programmes d'édition d'image disponibles pour chaque plate-forme. En plus des graphismes 3D, les jeux nécessitent une interface graphique utilisateur (GUI) pour décrire les menus, les boutons, bref la partie interface avec l'utilisateur. Torque contient un outil robuste d'édition de GUI. Une nouvelle fois, vous pouvez voir plus loin pour un bref aperçu, ou allez directement au chapitre « Éditeur GUI » de ce document. Jetons un coup d'œil rapide à chacun des outils mentionnés ci-dessus. 1.4.3.1 Éditeur de terrain/de mission Comme décrit précédemment, l'éditeur de mission (Mission Editor) est un outil intégré au jeu comprenant deux éditeurs étroitement couplés entre eux fournissant l'épine dorsale pour la création de diverses zones pour votre jeu. Les composants majeurs de l'éditeur de monde (World Editor), l'éditeur de terrain (Terrain Editor), et le générateur de terrain. L'éditeur de monde est basé sur le WYSIWYG 5 vous permettant de construire, de placer, de dimensionner, de mettre à l'échelle et de faire pivoter des objets. L'éditeur de terrain et le générateur vous permettent de créer des mondes beaux et uniques, en employant des outils tels que la génération de terrain basée sur les fractales, les règles basées sur le placage de textures de terrain fractals, et la possibilité de manipuler finement les terrains. Référer vous au chapitre « Éditeur de mission » dans cette documentation pour avoir plus d'information sur ce puissant outil. 1.4.3.2 Création d'intérieurs/de constructions Ces éditeurs se concentrent sur la construction d'intérieurs sur le modèle BSP. Ce sont des outils très spécialisés pour la création et l'édition de brosses convexes et des outils pour le placage précis de textures. Lorsqu'ils sont utilisés en conjonction avec l'utilitaire Map2Dif fourni avec Torque, ces éditeurs peuvent être utilisés pour créer des constructions, et d'autres grandes structures. 1.4.3.3 Quake Army Knife (QuArK) Originellement développé pour créer des niveaux pour Quake, le Quake Army Knife, ou QuArK comme il est appelé, est un produit Open Source disponible gratuitement. Desmond Fletcher6 a représenté la communauté TGE dans la communauté de développement QuArK, et a fourni plusieurs tutoriels sur l'utilisation de QuArK avec Torque. Les guides suivants vous aideront pour commencer la création d'intérieurs dans QuArK. • • Site officiel de QuArK Tutoriels sur QuArK de Desmond Fletcher Évidemment, n'importe quel éditeur BSP pouvant exporter au format Valve 220 (fichiers .map), peut être utilisé avec Torque. Actuellement, il n'y a pas d'éditeur .map natif disponible pour la plate-forme Macintosch, 5 6 What You See Is What You Get : tel écran-tel écrit Membre de la communauté GarageGame 7 / 223 Documentation de Torque V1.3.x cependant QuArK fonctionnera sous l'émulateur Virtual PC 6. 1.4.3.4 Création d'objets DTS Torque utilise le format DTS pour stocker et rendre de petites formes, visuellement complexes, mais simples en termes de collisions et autres interactions avec l'environnement. Un exemple de ceci serait le modèle d'un joueur, des éléments, des véhicules, ou des armes. Tous ces éléments sont très détaillés, mais dans un souci d'efficacité, et de vitesse de traitement, utilisez des combinaisons relativement simples pour les interactions avec l'environnement. Le format DTS est supporté par plusieurs programmes de modélisation 3D. Ci-dessous, vous trouverez les outils principaux pour l'exportation de modèles DTS pour le TGE. 1.4.3.4.1 Blender Torque supporte entièrement Blender, le puissant et Open Source outil de modélisation. Blender est disponible pour Linux, Macintosh, et Microsoft Windows, et il est gratuit ! L'exportateur de Blendeur vous permet de tirer avantage de toutes les fonctionnalités du DTS. 1.4.3.4.2 MilkShape MLK est un outil de modélisation simple pour PC créé pour les développeurs créant des modèles pour Half Life et Quake. MilkShape est peu coûteux, avec une période de test gratuite de 30 jours et un coût d'enregistrement de seulement $20. L'importation des modèles de MilkShape dans TGE requiert l'utilisation de ms2dtsExporter.dll, fourni avec Torque, pour gérer l'exportation. Ci-dessous, vous trouverez quelques liens pour vous aider à commencer avec MilkShape. • • Site officiel de MilkShape Tutoriels officiels de MilkShape 1.4.3.4.3 3D Studio Max 3D Studio Max est un modeleur et un éditeur d'animations de haut niveau, coûtant environ $3500 par utilisateur. Il est complexe et puissant, mais si vous utilisez 3D Studios Max vous savez déjà tout ceci. L'importation des modèles et des données de 3D Studio Max dans TGE est un processus complexe. Ceci est principalement dû au fait que Torque supporte beaucoup de puissantes possibilités d'animation, incluant les animations multiples avec traitement des boîtes d'encadrement et des niveaux de détail (Level of Detail – LOD). Un plug-in 3D Studio Max, max2dtsExporter.dle, fourni avec Torque, gère le travail d'exportation. Veuillez vous référer aux excellents tutoriels et explications ci-dessous pour plus ample assistante. • Tutoriels vidéo 3D Buzz 3DS MAX 1.4.3.4.4 Autres éditeurs de modèles La communauté GarageGames est dans le processus de création d'exportateurs pour plusieurs programmes de modélisation, incluant Maya et Lightware. Un exportateur officiel Maya sera bientôt disponible, ainsi qu'un exportateur gameSpace/trueSpace de Caligari. 1.4.3.5 Création de textures Comme indiqué ci-dessus, chacun de ces types de modèles supporte fortement les textures. Torque peut charger des fichiers aux formats BMP, GIF, JPEG et PNG. Tous les programmes capables de créer ces formats peuvent être utilisés pour éditer les textures. Sont inclus les logiciels populaires suivants : Adobe Photoshop, GIMP et Paint Shop Pro. 1.4.3.6 Éditeurs GUI L'éditeur GUI est un outil intégré conçu pour faciliter le processus de création d'interfaces intuitives pour un jeu. Ce qui est important, c'est qu'il est intégré, ce qui permet un retour immédiat sur le projet en cours de création. Il est possible de créer des interfaces très complexes avec l'éditeur GUI (GUI Editor), bien que l'éditeur lui-même soit direct et simple à utiliser. Les fichiers GUI dans le moteur sont normalement sauvegardés avec l'extension .gui, mais il est possible de décrire une GUI dans un fichier de script normal 8 / 223 Documentation de Torque V1.3.x .cs. La description d'une interface dans un script utilise les mêmes règles syntaxiques que dans n'importe quel autre script Torque, ainsi il est nécessaire d'avoir une connaissance de base de Torque Basic pour être capable d'utiliser l'éditeur GUI et le système GUI dans Torque dans toute son ampleur. Reportez-vous à l'introduction de l'éditeur GUI GarageGames pour être opérationnel avec l'éditeur GUI aussi rapidement que possible. 1.5 Quoi faire maintenant ? Maintenant que vous êtes familiarisé avec quelques concepts de base du TGE, vous êtes prêt à commencer l'apprentissage en détail de Torque. La première étape pour ce faire sera le téléchargement du code source du moteur et de l'installer sur votre système (annexe B). Vous devrez faire cela, juste pour installer le SDK de Torque et arriver à une situation où vous pouvez commencer à travailler. Depuis que le guide d'installation pas à pas est très détaillé, il peut paraître un peu brut. Mais il n'est pas si mauvais, et vous ne devrez avoir aucun problème pour vous en sortir. Dans le sommaire de l'annexe B, vous pouvez voir où aller ensuite, quel que soit la partie du moteur que vous souhaitez apprendre. Le parcours que vous prendrez dans l'apprentissage de Torque dépendra de ce que vous tentez de faire avec le moteur. Êtes-vous partant sur la conception d'un jeu commercial ? Ou partant pour créer votre jeu de rêve, sans vous préoccuper sur la viabilité commerciale ? Voulez-vous juste apprendre, pour vous amuser, le développement de jeux avec un moteur avancé et compétent ? Tous ces buts, et plus, sont très valables et dignes d'intérêt. Ce guide ne donne pas tout sur Torque, mais s'efforce de vous donner un bon aperçu et une bonne référence pour chaque élément impliqué dans un développement avec Torque. Nous ne répondrons pas à toutes les questions que vous pourrez vous poser, loin de là, mais vous finirez, globalement, avec un très bon ressenti sur le travail avec Torque. Bon, vous partez en bonne position ! Continuez la lecture. Bien sûr, il serait idiot de dire que ceci est le seul guide existant sur Torque dont vous aurez besoin. Une chose importante sur Torque est qu'il y a, maintenant, beaucoup de ressources et beaucoup de documentations associées. Certaines des meilleures ressources additionnelles sont listées ci-dessous. Après avoir lu les parties de ce guide nécessaires à votre projet particulier, vous pouvez vérifier les collections de ressources additionnelles suivantes pour déterminer où aller ensuite : • • • Probablement la meilleure liste de guides utiles et compréhensibles sur Torque pouvant être trouvés sur la page principale de Torque. Cette page conserve une liste à jour des meilleures ressources disponibles. Parcourez ces sections, et vous trouverez de nombreux guides utiles. En plus, le site Internet de GarageGames héberge d'abondantes FAQ7, tutoriels et autres ressources. Ces sections peuvent être difficiles à parcourir, simplement parce qu'elles contiennent trop de choses, mais chacune contient beaucoup de « pépites d'or » pouvant vous êtes extrêmement utiles pour votre projet. Une documentation spécifique sur le code source du moteur est aussi disponible. Nous ne fournissons pas les détails du code source du moteur dans ce guide, car beaucoup d'équipes n'auront pas besoin de changer ou modifier significativement le code source. Bien sûr, n'importe quel propriétaire du SDK est plus que bienvenu pour faire les changements qu'il désire ! C'est pour cette raison que nous fournissons le code source aux licenciés de Torque, avec la documentation source du moteur. Il y a des collections de ressources officielles GarageGames. Mais beaucoup plus de ressources abondent, la plupart étant créées par des membres talentueux de la communauté GarageGames. Tant que nous sommes sur le sujet de la communauté, vous devrez comprendre que vous êtes entré dans l'une des meilleures communautés en ligne jamais créée. C'est un bénéfice majeur d'un propriétaire de Torque. Les membres de la communauté GG sont extrêmement actifs, et chacun aide l'autre avec tous types de questions et problèmes – novices et experts de façon semblable. S'il vous plaît, conservez à l'esprit que la communauté doit être traitée avec respect, et n'aime pas les exigences. Si vous avez une question sur quelque chose, et la publiez claire, bien écrite, respectueusement, vous serez stupéfié de l'aide que vous pouvez obtenir. Une fois que vous avez le moteur, vous avez accès au forum des propriétaires de Torque, où 7 Frequently Asked Questions, ou Foire Aux Questions. 9 / 223 Documentation de Torque V1.3.x les questions relatives au moteur peuvent être publiées. En outre, beaucoup de maîtres sont disponibles dans le le canal IRC8 GarageGames. Impliquez-vous dans la communauté, c'est super ! OK, maintenant lisez bien, et soyez prêt à vous amuser à faire votre jeu ! 8 IRC : Internet Relay Chat – Système de dialogue en direct sur Internet en mode texte. 10 / 223 Documentation de Torque V1.3.x 2 Création d'un jeu indépendant à succès avec Torque 2.1 Aperçu Comment créez-vous un jeu ? C'est une chose décourageante. Beaucoup de jeux aujourd'hui occupent une équipe d'une douzaine (ou parfois centaine) de personnes, avec des budgets de plusieurs millions de dollars, et nécessitent plusieurs années. Comment pouvez-vous réussir ? Vous utilisez un moteur puissant vous aidant à réaliser vos buts de développement de jeu. C'est déjà une bonne première étape. Mais Torque, comme n'importe quel moteur commercial disponible, est gros. Vraiment gros. Cela signifie qu'il peut être difficile d'apprendre tout ce qu'il y a à connaître dessus, et de savoir où commencer l'apprentissage. C'est pour cette raison que nous avons créé ce document. Nous savons qu'il peut être difficile de comprendre comment analyser une base énorme de code source du moteur pour la création d'un jeu réel. Ainsi, quelle est la première étape ? Comment commencer votre projet ? Nous aborderons de telles questions dans ce chapitre. Dans le reste de ce document, nous entrerons dans des détails concrets sur l'utilisation du TGE et ses outils annexes. Mais premièrement, nous avons besoin de regarder le processus général du développement de jeux. Dans ce chapitre, nous offrons un plan de création d'un jeu profitable. Nous discuterons du processus de création, mais nous ne parlerons pas de généralités de haut niveau. Chaque étape dans le périmètre suivant est soutenue avec les sections « Dans le monde réel », qui parle du développement de Marble Blast. Marble Blast est un jeu réussi avec Torque, et beaucoup de leçons peuvent être glanées de son développement. Marble Blast démontre aussi que vous n'avez pas à créer un jeu de tir (FPS)9 pour produire rapidement un jeu réussi avec Torque. Figure 1 : Nous étudierons l'histoire du développement de Marble Blast pour illustrer comment les conseils de ce chapitre fonctionne dans le monde réel. Bien sûr, l'ensemble des licenciés de Torque ne crée pas des jeux dans un but commercial. Certains ont des idées superficielles et prennent Torque dans l'unique but de les implémenter en utilisant une base de moteur stable et reconnu pour les construire. Certains licenciés souhaitent être embauchés dans une société de développement de grands jeux, et prennent une licence d'un moteur bien connu comme Torque afin de montrer ce qu'ils peuvent faire avec. D'autres licenciés veulent simplement jouer avec un moteur puissant. D'autres encore veulent faire des jeux, mais ne souhaitent pas en tirer un quelconque profit, ils veulent juste essayer concrétiser leurs rêves de jeux, et leurs donner vie. 9 FPS : First-Person Shooter - Jeu dans lequel on tire sur les autres à partir d'un point de vue subjectif, dans le style de Doom. 11 / 223 Documentation de Torque V1.3.x Ce sont d'excellentes raisons pour obtenir une licence du moteur. Votre motivation personnelle pour l'achat de Torque n'a aucune importance, les points discutés dans ce chapitre peuvent être étudiés et adaptés dans n'importe quel projet de développement. Nous parlons réellement ici du processus de développement d'un jeu s'appliquant particulièrement à un jeu indépendant. La raison pour laquelle nous nous focalisons sur la production de jeux indépendants dans ce chapitre est que la conception de jeux commerciaux avec une petite équipe est plus difficile que la plupart des autres projets entrepris avec le moteur. Ce chapitre va dans assez de détail sur le travail avec Torque que vous commencerez à avoir une idée de l'utilisation du moteur avec des projets réels. Bien, jetons un coup d'œil. Pour – les équipes concernées sur la réalisation de jeux commerciaux, la première étape est souvent la plus importante. 2.2 Étape 1 : soyez réaliste Lors de la création d'un jeu, commencer par la conception d'un jeu au-delà de ce que votre équipe peut raisonnablement accomplir est une des meilleures façons pour être certain que votre projet n'aboutira pas. D'un autre côté, commencer par un objectif raisonnable est la meilleure manière pour que votre projet soit couronné de succès. C'est un des aspects avec lequel luttent la plupart des développeurs indépendants. Vous devez réaliser que, à moins que vous travailliez avec une équipe d'une centaine de personnes, et ayez une dizaine de millions de dollars de budget, vous ne serez pas capable de créer un Half-Life 2, ou n'importe quel jeu d'ampleur similaire. Bien sûr, personne ne vous empêche d'en faire un, et nous vous souhaiterons bonne chance dans tous vos efforts. La création du jeu de vos rêves, ou seulement une partie, peut être d'un grand agrément, et amusant. Ce guide, cependant, offre des conseils sur la manière de faire des jeux commerciaux, avec une petite équipe. Si vous êtes un indépendant, et que vous voulez réussir, vous devez partir sur la conception d'un jeu indépendant. • Réalisez que le développement d'un jeu est difficile et dur et dure longtemps il a fallu deux années à Dynamix pour réaliser Tribes 2, avec une équipe de plus de 30 professionnels de jeu expérimentés et un budget important. Doom 3 et Half-Life ont pris six années de développement, avec une grande équipe et un budget important. La création d'un jeu commercial à succès n'est pas une tâche aisée – indépendamment de la technologie ou du moteur utilisés. Le fait que vous utilisiez une plate-forme mature telle que Torque pour votre technologie centrale sauvera définitivement votre temps par rapport aux autres développeurs de jeu devant créer leurs propres moteurs et outils. Ceci est un avantage de l'utilisation de Torque, mais aucun moteur n'est magique. Vous devez encore être réaliste. Partez avec une conception de jeu à votre échelle. Vous pouvez créer des jeux amusants et existants, sans entrer dans une lutte futile contre des jeux de développeurs professionnels. De même, de grandes équipes avec des fonds importants doivent être vigilantes sur la conception de leurs jeux. Plus vous créerez votre jeu solide et amusant, et meilleur il sera. Un thème récurrent que vous rencontrerez tout au long de ce guide est que le gameplay10 devra dicter les fonctionnalités, rien d'autre. Une fonctionnalité devra uniquement être implémentée que si elle rend le jeu beaucoup plus 10 Cet anglicisme n'a pas d'équivalent en français. Il recouvre plusieurs sens que l'on pourrait tenter de résumer ainsi : le gameplay serait les règles du jeu, la manière dont le joueur est censé y jouer, la fluidité de ces règles une fois appliquées à l'environnement du jeu, et également la manière dont le joueur peut jouer, les possibilités offertes par l'environnement (on peut parfois découvrir une possibilité d'action qui n'était pas prévue par les programmeurs mais toutefois permise par l'environnement et l'ensemble des règles). (Wikipédia) 12 / 223 Documentation de Torque V1.3.x amusant. Sinon, vous finirez avec des fonctionnalités qui pourront altérer le gameplay, et qui n'existeront que pour avoir des points supplémentaires pour la partie marketing. La guerre sur le nombre de fonctionnalités est injustifiée et idiote, les concepteurs futés de jeux l'évitent. • Soyez créatif ! Être réaliste ne signifie pas que vous ne pouvez pas être créatif. En fait, l'opposé est nécessaire : un projet créatif de jeu vous permettra de concurrencer les jeux des grands développeurs, même si ses fonctionnalités ne sont pas aussi grandes. Ce n'est pas parce que l'ampleur de votre jeu correspond au niveau de vos ressources que vous êtes contraint de faire un jeu rustique ou laid. C'est un des secteurs où les développeurs indépendants ont un énorme avantage dans la compétition de marché ! Le fait que vous utilisiez vos propres moyens signifie que vous pouvez penser et concevoir comme le feraient les grands éditeurs et développeurs. Vous pouvez être original, vous pouvez être loufoque, vous pouvez réaliser votre jeu rigolo. Soyez juste certain que l'ampleur du projet corresponde à ce que vous pouvez raisonnablement faire. Dans le monde réel : Ici à GarageGames, nous avions lancé la création de Marble Blast en 2002. Marble Blast commença – à partir de rien – avec ce que nous pensions être un plan très raisonnable, un jeu de course de billes rapide, amusant et simple. Cependant, même avec notre concept initial raisonnable, il était difficile de résister à la tentation d'accroître l'envergure du projet alors que nous avions commencé le développement. Vous verrez certains de ces aspects et, en continuant dans ce chapitre, comment nous les avons traités. Figure 2 : Marble Blast – construction finale. Même avec un jeu relativement simple à l'esprit, la production d'un jeu amusant est une longue route. Je me contenterai de dire qu'il est rare en effet de proposer un projet initial détaillé qui fonctionnera parfaitement au premier essai. Vous devrez revoir votre conception – voir ce qui fonctionne et ce qui ne fonctionne pas. 2.3 Étape 2 : identifiez les technologies nécessaires Dans le cadre d'un projet réaliste, pour commencer la réalisation, vous aurez besoin d'entreprendre le processus d'identification des composants majeurs nécessaires pour accomplir le jeu. Regardez les systèmes de gameplay majeurs de votre projet et déterminez quels genres de technologie seront 13 / 223 Documentation de Torque V1.3.x nécessaires pour les supporter. • Restez simple À ce point, il n'y a pas besoin de décrire de manière extrêmement détaillée vos technologies. En fait, vous devriez éviter de le faire le plus possible. Construire une description détaillée et une analyse d'une partie de technologie pouvant être rejetées plus tard serait simplement une perte de temps. Votre but ici est d'arriver au niveau du prototype aussi rapidement que possible. Identifiez les gros composants dont vous avez besoin – les grands secteurs sur lesquels vous devrez vous focaliser – et allez-y. Dans le monde réel : Par exemple, avec Marble Blast, nous savions immédiatement que le cœur du succès du jeu serait un système physique de billes. Ceci serait une facette majeure du gameplay, et nous savions qu'il fallait nous concentrer sur la physique des billes dès le début. Les parcours des courses sont les autres parties importantes du gameplay de Marble Blast. Avoir la physique des billes n'apporterait pas beaucoup si les parcours des billes étaient ennuyeux. Ainsi, nous avons su, ici, que nous devrions nous concentrer sur notre niveau de projet. En particulier, nous savions que nous voulions des parcours de jeu grands, complexes, courbes et mobiles. Figure 3 : Marble Blast – projet du niveau final – nous savions que la création de parcours de course excitants et complexes devrait être une caractéristique clef du gameplay de Marble Blast. L'identification de ces composants clefs au plus tôt nous a permis de focaliser nos efforts sur les aspects les plus importants du jeu. À ce point, nous pouvions sembler assez superficiels. Il semble que nous avons tout correctement identifié. Il s'avère cependant, que les choses n'étaient pas aussi simples qu'elles pouvaient paraître. Regardons le premier exemple sur lequel nous nous sommes focalisés, mais qui fut supprimé plus tard : Savez-vous que Marble Blast était originalement prévu pour être un jeu multijoueurs ? Ainsi, au début, nous avions identifié que le mode multijoueurs comme une technologie centrale sur laquelle se focaliser. Bien sûr, ceci s'est avéré ne pas être du tout le cas. Comme vous le verrez, même avec un projet initial réaliste du jeu, un tas de révisions et d'améliorations seront nécessaires avant que votre jeu soit bien ficelé. Même, le plus expérimenté des créateurs de jeux est confronté à ce fait. En vérité, plus vous serez expérimenté, plus vous identifierez ce processus d'améliorations graduelles pour développer un jeu de qualité supérieure. C'est pourquoi il est important d'identifier l'étendue des secteurs technologiques sur lesquels vous pensez tout de suite vous concentrer. Arriver rapidement à un prototype de votre jeu est absolument essentiel. 14 / 223 Documentation de Torque V1.3.x 2.4 Étape 3 : acquisition de technologies existantes Maintenant, vous avez une idée initiale des technologies requises pour votre projet. Ainsi, il est temps d'arriver à comprendre la meilleure manière pour construire ces technologies. Bien sûr, si vous souhaitez finir votre jeu aussi rapidement que possible, la meilleure solution est l'acquisition de technologies existantes. Vous travaillez avec Torque, ainsi vous avez obtenu un moteur de jeux complet, et de haut niveau qui peut concurrencez pied à pied les technologies d'un montant de plusieurs centaines de milliers de dollars. Ainsi, bon début, vous avez sauvé beaucoup de temps juste en utilisant un tel moteur. Maintenant, il est temps de détailler plus. Vous devez comprendre quelles sont les technologies supportées immédiatement par Torque, avec peu ou pas d'effort, et celles qui nécessiteront des changements ou améliorations assez substantiels. Vous devez aussi déterminer si des systèmes du gameplay de votre projet nécessiteront des technologies totalement nouvelles. • Commencez l'apprentissage du moteur... Pour les débutants, le processus d'identification des parties de technologie qui fonctionneront avec Torque et celles qui nécessiteront des modifications peut être difficile. Si vous ne connaissez pas déjà le moteur, comment identifiez-vous ce que vous pouvez utiliser et ce que vous devrez modifier ? La réponse est simple : lors de l'utilisation de partie de technologie, vous aurez à passer du temps pour appréhender ce qu'il peut faire et ce qu'il ne peut pas faire. Torque vous donne un coup de main important dans le développement, vous devrez juste passer du temps pour identifier ce qu'il fait de mieux, et comment l'utiliser pour le faire. Heureusement, il y a un grand nombre de guides pour vous aider à cela ! Aussi loin que va la technologie, testez les chapitres sur les scripts et l'aperçu du moteur. De même, portez attention à l'ouvrage « 3D Game Programming All-in-One » de Ken Finney, qui couvre Torque en détail. Il y a d'autres livres sur Torque, ainsi vous aurez encore plus d'aide lorsqu'il sera temps d'étudier le moteur. Sur le site de GarageGames, regardez les pages sur les tutoriels de Torque, les forums, et les zones de ressources soumises par la communauté. N'oubliez pas l'un ou l'autre des canaux IRC, le canal #garagegames est habituellement plein de membres bien informés et utiles de la communauté qui sont disposés à vous donner un coup de main – aussi longtemps que vous resterez poli et que vous ferez des efforts pour l'exposition de vos problèmes. Bien sûr, continuer avec ce livre est aussi une bonne idée. Il y a beaucoup d'outils et de ressources pour vous aider dans l'apprentissage du moteur, utilisez donc tout ce dont vous aurez besoin. • Réévaluez votre projet... La plupart des réévaluations surviennent après la phase de prototypage. Mais souvent, vous pouvez réaliser des améliorations plus tôt. Est-ce que la liste des modifications que vous devrez faire sur Torque est longue ? En plus d'une longue liste de modifications, devez-vous créer une poignée de nouvelles technologies ? Si cela est, vous devez probablement relire le premier élément de cette liste : soyez réaliste avec votre projet ! Beaucoup de jeux professionnels ont été créés avec Torque, dans une large variété de genres et de styles. Si vous pensez que vous devez modifier énormément Torque pour obtenir votre jeu, vous devrez vous poser quelques questions. Êtes-vous certain de savoir ce que Torque peut faire ? Votre projet de jeu est-il vraiment réaliste et rentable ? Si cela n'est pas le cas, retournez à l'étape 1 et mettez votre équipe sur un jeu réalisable pouvant être mené à bien ! • Maintenant, vous pouvez « pomper » n'importe quoi, n'importe où... 15 / 223 Documentation de Torque V1.3.x Reprenez à votre compte Torque et la communauté de développement environnante autant que possible. Souvenez-vous qu'il existe une pléthore librement disponible de petits bouts de codes, de tutoriels, et autres ressources sur le site de GarageGames qui peuvent tous vous aider à réduire votre temps de développement. Sans compter que Torque fournit quelques kits de démarrage que vous pouvez utiliser comme base. Testez-les et économisez le temps de création de ces bases de démarrage. Il y a aussi beaucoup de packs de codes et de contenus disponibles qui peuvent vous aider grandement à réduire votre temps de développement. Votre jeu requiert-il plus d'éclairages réalistes que ceux disponibles en stock dans Torque ? Testez le Synapse Gaming Lighting Pack. Besoin de géométries et d'intérieurs au visuel impressionnant ? Testez le Timothy Aste's Content Packs. Désirez-vous des modèles d'arbres et d'éléments extérieurs ? Testez le BraveTree: Tree Pack Pro #1 et le BraveTree: Environment Pack Pro. Votre jeu a-t-il des armes et des explosions ? Jetez un coup d'œil sur les Mojo audio packs. Construction d'un jeu RTS11 ? Testez le RTS Foundation Pack. Employez tout ceci ! Ne vous inquiétez pas si quelque chose fait exactement ce que vous voulez, soyez malin sur l'acquisition des éléments des packs. Ils ne sont pas chers, et vous économiserez du temps de développement, si votre jeu requiert le type de contenu que les packs fournissent. Dans le monde réel : Avec Marble Blast, nous savions que Torque pouvait faire du bon travail avec les types de niveaux grands et complexes que nous voulions être capables de parcourir. Ainsi, nous savions que nous n'aurions pas à perdre beaucoup de temps avec ça, judicieuse technologie. D'un autre côté, nous avons réalisé qu'un nouveau système physique des billes serait nécessaire. Nous avons reconnu qu'un grand nombre de codes personnalisés serait nécessaire pour obtenir une sensation juste de l'aspect physique. Depuis que la fonctionnalité multijoueurs était une grosse partie de notre projet initial, nous avons également évalué la technologie dont nous aurions besoin. Bien sûr, Torque inclut un support remarquable du réseau, ainsi cette technologie centrale n'était pas un souci. Pour créer une expérience multijoueurs amusante, fonction du gameplay de Marble Blast, nous savions que nous aurions besoin de définir le fonctionnement de la partie réseau impliquée dans la physique complexe des billes. Cela semblait assez raisonnable, pour être certain que nous pouvions intégrer le mode multijoueurs dans Marble Blast. Vous verrez bientôt pourquoi nous avons cependant décidé de le retirer. Tels sont les secteurs principaux de technologie que nous identifions, à ce moment, comme importants pour ce jeu. Cependant, il y avait un autre secteur auquel nous n'avions pas pensé plus tôt : le changement de certaines technologies de rendu. Nous parlerons de cela plus tard, mais nous avons finalement réalisé une modification essentielle de la technologie centrale des procédures de rendu de Torque, afin que Marble Blast ait un aspect plus brillant et plus vif. Lors de notre premier passage pour l'identification des technologies importantes et la compréhension des celles-ci, nous n'avons pas identifié ceci comme étant un secteur de soucis central. Comme vous le verrez, ceci signifiait que nous avons dû adapter notre programme de développement dans les dernières étapes. 11 RTS = Real Time Strategy – jeu de stratégie se déroulant en « temps réel ». En fait, les durées sont souvent fantaisistes ou accélérées, mais le principe est qu'il n'existe pas d'option « pause » pour réfléchir un peu ou souffler un coup dans des parties qui peuvent durer des heures voire des jours. 16 / 223 Documentation de Torque V1.3.x Figure 4 : Marble Blast – aspect final – nous avons adapté notre projet afin de produire des niveaux colorés et ombrés à l'aspect propre et brillant Sans aucun doute, vous arriverez à de telles situations. La plupart des projets le font. Vous pouvez spécifier un élément de technologie qui finalement sera retiré, et vous pouvez rater un gros élément de technologie auquel vous n'aurez pas pensé et qui deviendra un problème. Aussi longtemps que vous identifierez la majorité de vos technologies clefs et apprendrez comment les implémenter au mieux – l'acquisition de technologies existantes est une opportunité possible –, vous serez sur le bon chemin. Souvenez-vous, tout au long de la période durant laquelle vous pensez à toute cette technologie et tout ce contenu, que votre intérêt premier doit être dans le gameplay. Soyez concerné uniquement par les technologies qui amélioreront la structure de votre gameplay. 2.5 Étape 4 : construction d'un prototype grossier et rapide À ce point, vous êtes sur le bon chemin. Vous avez un projet qui semble raisonnable. Vous avez une idée des contenus et des technologies dont vous aurez besoin. Et vous avez une idée des éléments de technologie nécessitant d'être créés, et ceux qui pourront réutiliser ou modifier des composants existants. La prochaine étape est de réaliser un prototype grossier et rapide pour votre jeu. Réalisez des prototypes tôt et souvent, et votre jeu aura une bien meilleure chance de succès. Comme nous le verrons, des prototypes fréquents étaient la clef du développement de Marble Blast, il en est de même pour n'importe quel projet grand et moderne. Il est important que bien comprendre ce qu'est un prototype et comment il devrait fonctionner. Il y a plusieurs points importants à garder à l'esprit lors de la création d'un prototype pour un jeu : • Gardez un visuel simple... À ce point, ne vous inquiétez pas de l'aspect de votre prototype. Vous perdriez beaucoup trop de temps pour la création visuelle avant même de savoir si votre jeu sera actuellement bon. Le point principal du prototypage est d'obtenir rapidement une maquette fonctionnelle de votre gameplay. Le point ici est de tester si vos idées de projet de jeu seront jouables actuellement. Ainsi, obtenez une maquette fonctionnelle. Vous serez surpris du nombre de révisions d'un projet de jeu pouvant être effectués précocement. Réalisez un prototype de votre jeu aussi vite que possible. Vous utilisez ce prototype pour commencer l'examen de votre concept, et l'identification des secteurs nécessitants d'être étoffés, modifiés ou retirés. En créant assez tôt un prototype et en évaluant de façon critique les systèmes de votre gameplay, vous aurez une meilleure chance d'identifier ce qui marche et ce qui ne marche pas, avant d'investir du temps dans l'implémentation de versions complètes ou de contenu qui seront rejetés plus tard dans le développement. Même si votre gameplay est fortement dépendant du graphisme – par exemple, si vous êtes en train de réaliser un jeu d'action – vous ne devrez pas vous inquiéter de l'aspect à ce point. Ayez les composants de rendu que vous avez besoin pour la 17 / 223 Documentation de Torque V1.3.x maquette du gameplay, et laissez les raffinements pour plus tard. • Ne vous inquiétez pas de la perfection Votre graphisme n'a certainement pas besoin d'être parfait, ni d'ailleurs votre code ou le comportement de votre gameplay. Nous le rabâchons ici, mais c'est important : faites des choses fonctionnant d'une manière simple. C'est tout ce dont vous devrez vous préoccuper lors de la première phase d'un prototype. Si vous désirez obtenir votre jeu le plus rapidement possible, et terminez avec un gameplay solide et amusant, vous voudrez vous permettre de passer le maximum de temps pour peaufiner votre jeu. Ainsi, l'obtention du prototype le plus rapidement possible est très importante. Lors de l'avancement du développement, vous réitérez votre projet et vos prototypes, l'achèvement et le peaufinage de vos systèmes et de leurs comportements et contenus apparaîtront naturellement. Lisez l'étape 5 pour quelques trucs sur la réitération et pour voir comment le prototypage a aidé dans le développement de Marbel Blast. • Utilisez une interface GUI simple Comme toutes choses à ce niveau, vous ne devrez pas encore passer beaucoup de temps sur votre GUI. Vous pouvez et devez penser à une conception intelligente, efficace, élégante d'une GUI, mais vous nedevrez pas soigner votre GUI, en terme d'apparence. Votre prototype initial certainement peut, et souvent il doit, être une maquette et tester les fonctionnalités de votre interface, mais ne passez pas de temps sur son apparence. Pour voir quelques exemples sur comment obtenir rapidement et simplement un prototype de jeu fonctionnel, testez les événements Game-in-A-Day dans la communauté GarageGames. Les événements Game-In-ADay ont été lancés par des membres de la communauté GarageGames, et ils organisent des événements où des concepteurs de jeux, des programmeurs, et des artistes peuvent voir quels types de jeux ils peuvent créer en un week-end, souvent en utilisant le TGE. Dans le monde réel : Figure 5 : Marble Blast – prototype - nous avons construit le prototype de Marble Blast en modifiant le FPS Starter Kit, comme le feraient d'autres équipes souhaitant créer un jeu d'action. Avec seulement un programmeur par tâche, cela nous a pris 3 semaines pour aller de notre concept de jeu 18 / 223 Documentation de Torque V1.3.x initial au prototype de Marble Blast. Nous avons construit notre prototype exactement de la manière que la plupart des licenciés de Torque le font – en modifiant le FPS Starter Kit. Tout comme le ferait n'importe quelle autre équipe, nous avons utilisé l'éditeur GUI de Torque pour obtenir une GUI dépouillée fonctionnant pour un prototype Marble Blast. Tout comme n'importe quelle autre équipe, nous avons utilisé l'éditeur de mission de Torque pour assembler nos niveaux de prototype, et avons continué à les affiner tout au long du développement. Comme n'importe qui, nous avons utilisé QuArk pour construire la géométrie des niveaux du prototype, et avons continué à l'utiliser au cours du développement. Nous avons construit la bille très simplement dans 3DS Max, et comme n'importe quelle équipe utilisant Torque, nous pouvions utiliser n'importe quel logiciel de modélisation 3D supporté. Nous avons créé nos textures dans Photoshop, et de nouveau, nous pouvions utiliser n'importe quel logiciel 2D parmi. La majeure partie du code du gameplay de Marble Blast a été prototypé en TorqueScript, et maintenu sous forme de script tout au long du développement ; ainsi, notre processus de programmation ressemblait à tout ce que n'importe quelle autre équipe Torque ferait. Figure 6 : Marble Blast – premier menu du prototype – nous avons construit un menu maquette et GUI extrêmement simple pour le prototype de Marble Blast. Ne passez pas de temps à peaufiner l'aspect de votre jeu dans la phase initiale de prototypage. Vous devez mettre toute votre énergie durant cette période sur le test, l'affinage, et l'édification de votre projet de gameplay. Comme mentionnée, notre priorité dans le prototype était d'obtenir une maquette de la physique des billes, ainsi nous pouvions commencer sa modification et son affinage. Mark Frohnmayer, un étudiant ingénieur, a abordé le problème et obtenu le prototype de la physique implémenté et fonctionnel dans le kit de démarrage de mission. Mark a construit toute la physique des billes lui-même, sachant qu'elle était assez simple et l'acquisition d'un logiciel tierce partie devrait être nécessaire. Pour la simulation, il a représenté la bille comme une simple sphère, et utilisé un algorithme personnalisé de détection de collision de sphères pour déterminer lorsqu'il y a interaction physique avec la sphère Pour la simulation physique, Mark a implémenté un simple système newtonien. Beaucoup de personnes sont effrayées à l'idée de programmer la physique, mais elle ne fait appel à rien d'extraordinaire même dans la physique compliquée de Marble Blast. Mark a simplement fait appel à ses souvenirs sur le physique de base qu'il avait apprise au lycée. Même en envisageant le pire, il a juste recherché sur Internet, les formules physiques qu'il ne se rappelait plus. Mark a programmé toute la physique des billes dans la classe C++ marble, qui est dérivée de la classe ShapeBase de Torque. La décision était de dériver la classe à partir de ShapeBase car elle offre beaucoup des fonctionnalités 3D que nous avions besoin, mais est assez générale pour être personnalisée facilement. ShapeBase fournit un support pour le chargement et l'affichage des formes 3D, la gestion du son, et elle offre la compatibilité avec la fonctionnalité des triggers12 de mission de Torque. Tout cela est encore assez général et n'inclut aucun code intempestif supplémentaire, ou fait d'hypothèse restrictive sur le comportement d'un 12 Trigger : mot anglais signifiant déclencheur, ce terme est surtout utilisé dans les bases de données. Il s'agit d'une fonction (ou d'un ensemble d'instructions) exécutée lorsqu'un événement se produit. 19 / 223 Documentation de Torque V1.3.x objet 3D. Si vous faites un jeu où les « personnages » ne sont pas des humanoïdes ou des véhicules, les dériver de ShapeBase est habituellement une bonne idée. Durant le prototypage, la physique des billes était super, nous pouvions éventuellement dire que nous avions un jeu amusant dans nos mains, mais la physique nécessitait un tas d'améliorations afin que le jeu puisse devenir réellement satisfaisant. Le prototypage de ce système nous a donné relativement tôt assez de temps pour tester et affiner le système physique. Figure 7 : Marble Blast – première physique de bille du prototype – notre premier modèle de la physique des billes a prouvé que notre idée de base du jeu pouvait être amusante, mais il y avait un tas d'améliorations à faire plus tard dans le développement. Durant le prototype, la bille capturée par les bords (voir image), se comportait mal avec une vitesse élevée, était délicate avec les sauts, et « s'enlisait » facilement. C'était parfait – à cette première étape du prototypage, nous voulions simplement faire une maquette et tester notre idée de base du gameplay. Il était facile de voir que le premier bilan du jeu serait positif. Le prototypage des niveaux du jeu n'était pas difficile. Nous avons utilisé des objets au format DIF, depuis que Torque supporte correctement les collisions avec des objets grands et complexes. Ensuite, nous avons commencé comme n'importe qui d'autre le ferait, en prenant les exemples de mission de Torque en stock et en les modifiant avec nos modèles DIF personnalisés. Le prototype incluait aussi des terrains. Nous pensions qu'il serait amusant d'être capable de faire la course sur des pistes à la fois grandes, tortueuses et complexes. Le système de la physique des billes semblait fonctionner correctement avec les terrains, mais comme vous le verrez dans la prochaine section, nous avons rapidement décidé de faire sans elle. Comme pour le mode multijoueurs, le prototypage si tôt nous a beaucoup aidés. Avec le système de physique des billes du prototype, nous avons commencé à réaliser de la complexité du support du mode multijoueurs. La représentation d'une physique des billes précise au travers d'un réseau commença à devenir un défi plus important que ce que nous avions prévu. À ce niveau, la capacité multijoueurs était encore d'actualité. Nous avions le solide noyau réseau de Torque, mais nous avons eu la première ombre d'un doute de savoir si le gameplay multijoueurs serait vraiment réalisable. Le doute sur la faisabilité du gameplay multijoueurs nous interrogea s'il était nécessaire de mettre fin à un grand jeu. S'il était réellement nécessaire au gameplay, il serait essentiel de trouver un système compliqué qui pourrait pleinement supporter le type de physique des billes que nous souhaitions. D'un autre côté, s'il semblait que le jeu pouvait tenir debout en mode monojoueur, nous pouvions rejeter la fonctionnalité 20 / 223 Documentation de Torque V1.3.x multijoueurs, sauvant ainsi tout le temps de développement, et rendre le noyau du jeu bien meilleur. Avec le prototype en main, nous pouvions voir le potentiel du jeu et être assurés qu'il pouvait, en fait, convenir en jeu monojoueur. Nous savions que le mode multijoueurs aurait été certainement amusant dans l'environnement de Marble Blast, mais notre meilleure estimation nous indiquait que le coût d'implémentation serait beaucoup trop élevé par rapport au bénéfice apporté au gameplay. Ainsi, nous avons pris la décision douloureuse de supprimer le mode multijoueurs de la conception du jeu. Personne dans l'équipe ne souhaitait prendre ce chemin, mais à la fin, tout le monde était d'accord. C'était une décision extrêmement difficile, mais très payante à la fin. La seule raison grâce à laquelle nous avons été capables de prendre cette décision aussi tôt, préservant ainsi un tas de temps de développement, était du fait que nous focalisions sur l'obtention tôt d'un prototype du jeu fonctionnel aussi rapidement que possible. Si nous avions attendu plus longtemps, nous aurions gaspillé notre travail et du temps de développement sur une fonctionnalité qui finalement serait rejetée. 2.6 Étape 5 : Itérez ! À ce point, vous avez un premier jet fonctionnel de la conception de votre gameplay. C'est une grosse étape, et vous devriez en être content. Maintenant, vous avez des décisions à prendre. Vous avez à évaluer sérieusement votre projet de jeu. Votre prototype a-t-il du potentiel ? Pouvez-vous voir son évolution vers un jeu vraiment amusant et attachant ? Si cela n'est pas le cas, ne vous sentez pas mal, car parfois, il y a dix idées de jeux minables avant d'en avoir une géniale. Si vous pouvez vous rendre compte que votre idée de jeu sera amusante juste en jouant avec la maquette du prototype, alors il est temps de faire cela. Vous êtes en voie de création d'un jeu à succès. Ensuite, vous commencerez à nouveau les itérations au travers de ces étapes de développement, travaillant vers le jeu final. Que signifie itérer votre développement ? Itérer signifie répéter. Essentiellement, vous avez besoin de parcourir les étapes de ce guide plusieurs fois. Une fois que vous avez votre prototype, vous aurez besoin de revoir la conception de votre jeu, et effectuer tous les ajustements nécessaires. Alors, vous devrez faire une phase plus détaillée d'identification des technologies qui seront requises pour réaliser un prototype plus détaillé et plus perfectionné. Avec ceci à l'esprit, vous aurez à trouver à nouveau la meilleure façon de construire ces technologies. Ensuite, vous devrez réaliser votre second prototype, et continuer avec lui. Jetons un coup d'œil plus précis sur cette idée : • Perfectionner Le fait que vous ayez réalisé la phase de prototypage très tôt signifie que vous pouvez commencer les améliorations de votre gameplay tout de suite. Si vous réalisez juste un prototype et que le projet original de votre gameplay fonctionne parfaitement, vous êtes victime d'une hallucination ou extrêmement chanceux. Dans tous les autres cas, votre prototype vous aidera à comprendre quelles parties de votre conception fonctionnent, celles qui ne fonctionnent pas. Avec un prototype fonctionnel, vous pouvez tester beaucoup plus rapidement d'autres idées de gameplay. • Commencer les itérations La plupart des projets doivent parcourir les étapes décrites dans ce chapitre un certain nombre de fois, se détaillant et se perfectionnant à chaque passe. Chaque fois que vous prototypez une idée ou technologie, vous en aurez une bien meilleure sur ce qui marche, et sur ce qui ne marche pas. Vous découvrirez les nouvelles choses dont vous 21 / 223 Documentation de Torque V1.3.x avez absolument besoin, et éliminerez celle que vous pouvez réellement supprimer. Ce processus vous aidera à rendre votre gameplay meilleur, et le même processus bénéficiera à vos technologies – vous pouvez essayer de multiples conceptions et implémentations de codes, et voir celles qui fonctionnent le mieux, s'améliorant et se perfectionnant à chaque passe. Le même bénéfice sera conféré à votre contenu artistique, et à tous les aspects de votre jeu. • Finaliser Finalement, après plusieurs prototypages, tests et perfectionnements, vous arriverez à une conception du gameplay qui serait correctement jouable à l'état de prototype et soutenue par de solides technologies. Ce processus de répétition des tests et des perfectionnements d'idées au travers de prototypage rapide est un exemple de conception itérative. Ce modèle de développement est puissant, spécialement pour les développeurs indépendants de jeux, où l'obtention d'un facteur d'amusement élevé – et ce, plus rapidement possible – est extrêmement importante. Une fois ce point atteint, où votre gameplay est très solide dans le prototype, réalisez quelque chose d'assez étonnant : vous avez un jeu que vous savez pouvoir rendre amusant. Vous aurez une preuve fonctionnelle. Avec cela, vous pouvez avancer avec confiance, en construisant les versions définitives de votre code et autres éléments, et assurer que votre jeu sera chouette, et aura ainsi, les meilleures chances de succès. Durant le développement de votre jeu, vous parcourrez les phases de développement standards, en intégrant les tests alpha et bêta, en finalisant le contenu artistique, en identifiant et en supprimant les bogues, et finalement... en diffusant le jeu ! Dans le monde réel : La conception itérative était absolument essentielle pour un développement rapide de Marble Blast. À chaque étape, nous avons évalué de manière critique le jeu et nous nous sommes constamment demandé ce qu'était l'âme du gameplay. Comme discuté avant, le mode multijoueurs était rejeté du projet après le prototype. Ceci était un exemple d'une idée de gameplay qui aurait été probablement amusante, mais qui aurait réclamé beaucoup trop de travail pour réellement être payante. Ainsi, nous avons décidé de la supprimer entièrement, bien que cela fut pénible à faire. Nous avons effectué ainsi des révisions dans les passes itératives ultérieures. Au deuxième prototype, plusieurs choses ont été supprimées. Révisions du gameplay : • Terrains : Nous avions une piste de course dans le prototype, et il fonctionnait correctement. Au travers du second prototype, nous avons commencé à étudier l'idée des pistes de course. Les surfaces courbes DIF que nous avions prototypées ont prouvé qu'il était beaucoup plus amusant de courir sur ces pistes que sur les terrains. Nous avons décidé que le jeu serait meilleur sans utilisation des terrains, bien qu'ils ne prendraient presque pas de temps de développement pour finaliser la technologie des terrains de course. Comme il s'est avéré, cette décision offrit un bénéfice-surprise. Sans terrain à s'occuper, nous avons été capables de supprimer des contraintes de la conception de nos niveaux. Soudain, l'idée surgit... « Hé, que se passe-t-il si nos niveaux arrivaient dans le ciel ? » Nous avons prototypé un niveau élevé, et le facteur d'amusement était évident. Une partie de l'excitation de Marble Blast provient de la course au travers des niveaux qui sont haut perchés dans le ciel, où les risques de chute semblent effrayants (même si vous n'êtes juste qu'une bille). 22 / 223 Documentation de Torque V1.3.x La suppression des terrains nous a aidée à proposer cette idée, et nous n'avons rien perdu, car le prototypage a révélé que les courses sur des terrains n'étaient pas aussi amusantes que les sources sur des surfaces DIF. Figure 8 : la course sur terrain était possible dans notre prototype du début • Figure 9 : mais la course sur des terrains ne semblait pas aussi amusante qu'elle le serait sur la géométrie « déjantée » formatée DIF que nous pourrions créer. Points de contrôle : Nous avons également rejeté un autre système du gameplay dans le second prototype. Au début, Marble Blast était conçu pour intégrer des points de contrôles. Lorsque le joueur atteignait un point de contrôle, leur progression devait être sauvegardée, leur permettant de choisir de repartir de ce point. Les points de contrôle auraient pu être utilisés comme dans beaucoup de jeu d'arcade, où le joueur doit atteindre chaque point de contrôle dans un certain laps de temps. Cela semblait être une grande idée, nous pourrions crée des niveaux longs et complexes, et nous pourrions utiliser les points de contrôle pour rendre les échecs moins frustrants, et donner aux débutants quelques minibuts à chaque étape. Après le second prototype, nous nous sommes aussi posé la question de l'inutilité de ce système. Comme avec les terrains, la fonctionnalité des points de contrôle était facile à implémenter, donc le temps de développement n'était pas un problème. Nous avons juste commencé à nous demander si les points de contrôle et sauvegardes seraient plus amusants que des niveaux plus courts et plus difficiles. Nous avons décidé de réaliser un nouveau prototype, des niveaux plus courts sans points de sauvegarde. Ce prototype était beaucoup plus amusant, le gameplay était plus simple – les points de contrôle ajoutaient une complexité non nécessaire. Le système sans points de contrôle s'est également plus aisément prêté à un gameplay d'action, au rythme rapide. Nous avons décidé de partir avec des niveaux plus courts et plus rapides qui ne requéraient plus du tout des points de sauvegarde. 23 / 223 Documentation de Torque V1.3.x Figure 10 : Marble Blast – points de contrôle du second prototype – notre projet de jeu initial incluait l'utilisation de points de contrôle (voir image), mais cette fonctionnalité n'ajoutait rien au gameplay, ainsi, elle a été supprimée. La conception itérative et le prototypage menèrent à un autre changement majeur dans Marble Blast. Nous avons originalement échoué à reconnaître un changement assez important de technologie qui était nécessaire afin de donner à Marble Blast le genre de sensation que nous souhaitions, et qu'il nécessitait. Pendant la progression de ce prototype, nous avons découvert que nous avions à modifier une partie de notre technologie de rendu. Marble Blast ne donnait pas de bonnes sensations en utilisant les rendus en stock dans Torque. L'éclairage n'était pas assez brillant, et nous souhaitions des contrastes pour tranchants. Au milieu du projet, nous avons décidé que nous avions besoin de consacrer du temps pour modifier certaines routines de rendu. Modifications de rendu : • Ombrage de Gouraud : Nous avons implémenté l'ombrage de Gouraud sur notre géométrie des niveaux. Torque précédemment supportait l'ombrage de vertex13, mais nous voulions le support complet de l'ombrage de Gouraud pour Marble Blast. Nous pensions que ce modèle d'ombrage fournirait un visuel plus brillant et plus précis. Notre implémentation analysait la géométrie du niveau durant le chargement de la mission, et effectuait la moyenne des normales des vertex les plus proches, donnant exactement l'apparence que nous souhaitions. • Stencil shadows14 : Les soft shadows (ombres douces) utilisées dans Torque n'ont pas l'aspect vif et propre que nous souhaitions pour Marble Blast. Afin d'obtenir l'aspect des ombres correctes dans le jeu, nous avons décidé d'essayer d'implémenter les stencil shadows. C'était un grand ajustement – le fait que notre géométrie était simple, et que nos niveaux n'avaient qu'une seule source lumineuse rendait le jeu bien adapté à cette technique. L'aspect obtenu avec les stencil shadows donnait exactement le type de détails précis que nous désirions. 13 Vertex : sommet d'un objet 3D. 14 Carmack's Reverse (ou Robust Stencil Shadow Volumes, ou encore Z-Fail) désigne une technique d'informatique graphique relative au calcul des ombres dans une scène graphique 3D. Il existe plusieurs techniques de projection d'ombres, chacune devant être utilisée en tenant compte du contexte technique. Carmack's Reverse est utilisé lorsque la scène graphique est éclairée selon le modèle unifié de lumière qui est la transcription informatique du comportement de la lumière dans le monde réel. 24 / 223 Documentation de Torque V1.3.x Figure 11 : Le rendu standard de Torque n'a pas l'aspect brillant et vif que nous souhaitions Figure 12 : Les modifications du rendu ont prouvé sa grande importance dans l'aspect, et plus encore dans le ressenti du jeu. Le résultat des modifications de rendu était un aspect bien meilleur, dans l'esprit arcade, pour l'amusement dans le jeu. Derrière ces changements de rendu, le système de caméra requerrait un gros travail durant le prototypage et durant le développement. Mais ceci était un autre domaine sur lequel nous avons échoué pour le considérer comme domaine clef durant notre toute première passe d'identification technologique. Cela a pris un bon moment pour obtenir une camera dans Marble Blast se comportant comme elle le devait. Les possibilités de la caméra de Torque sont très flexibles, ainsi nous n'avons rien eu besoin de modifier ou d'ajouter au système afin d'implémenter notre propre système de caméra. Nous avons juste dû changer le comportement de la caméra. Nous avons commencé à examiner des idées sur la manière de répondre de la caméra durant les quelques premiers prototypes, et avons continué jusqu'à plus de la moitié du projet. Nous avons finalement terminé avec un système facile à utiliser que fonctionne bien et que la plupart des gens trouvent très naturel. Figure 13 : Marble Blast – Système de caméra à mi-parcours – la modification de la caméra a pris beaucoup de temps. L'image illustre un prototype du système de caméra, avant que nos modifications de rendu n'aient été terminées. Par ce point, la caméra pouvait suivre correctement la bille, même dans des espaces étroits tels que des tunnels. Cela prendra plusieurs semaines de plus de finitions avant que la caméra ne soit totalement satisfaisante. Consacrer du temps à perfectionner ce système était très important pour les sensations du gameplay de Marble Blast. 25 / 223 Documentation de Torque V1.3.x Revenons sur la physique des billes qui représentait réellement le noyau central du gameplay, nous avons légèrement modifié la physique et le comportement de la bille dans chacun des prototypes. Nous avons fait beaucoup, beaucoup de prototypes de physiques des billes, en testant divers comportements sur différentes sortes de géométrie, et éventuellement avec différents états initiaux. Tandis que nous faisions beaucoup de miniprototypes, le système de la physique des billes prenait réellement forme en trois passes principales : • • • Le prototype de ce système est discuté précédemment dans l'étape 4, et invoquait juste une simulation newtonienne de base de la bille et fonctionnait avec une bonne détection des collisions. Dans la seconde itération principale du système de la physique des billes, Mark a corrigé un problème avec la bille se collant sur les bords. Pour faire suite à une suggestion de Tim Gift, il a aussi introduit la notion de vitesse de rotation en réponse à des bonds. Les bonds avec rotation ajoutent beaucoup au gameplay de Marble Blast. La troisième itération majeure du système de la physique des billes a eu lieu lors de l'introduction des plates-formes mobiles dans notre géométrie de niveau. Soudainement, nous avons dû prendre en compte les forces dynamiques appliquées sur la bille en déplaçant les niveaux. Les plates-formes mobiles se sont avérées être d'un grand amusement, ainsi l'extension de l'interaction de la bille avec elles valait plus que le temps et les efforts que Mark a porté dessus. Figure 14 : Marble Blast – physique finalisée des billes – nous avons terminé avec une grande simulation de la physique des billes, amusante à jouer. Ce système de révision et d'amélioration continue a eu comme conséquence que le jeu embarque un système de physique des billes bien réglé. Tout semblait correct et si nous avions fait qu'un couple de prototypes, et n'avions pas créé la bille amusante pour jouer avec ? Si cela avait été le cas, nous aurions tout de suite arrêté les frais et mis fin à la production de Marble Blast. C'est une autre leçon puissante à apprendre pour les développeurs indépendants : le fait de passer du temps à travailler sur une idée ou une fonctionnalité de jeu ne signifie pas que vous devrez la finir. Comme le disait Mark, « Si vous ajouter une fonctionnalité – même si elle prenait du temps à créer – ne soyez par effrayer à l'idée de la supprimer. Soyez dur. Quelque chose qui ne rend pas le jeu beaucoup plus amusant devrait disparaître. Commencez à travailler sur quelque chose qui rendra votre jeu meilleur, pas simplement plus grand. Et si votre idée de base de jeu ne concrétise pas et ne ne fonctionne pas bien, abandonnez alors le navire. Il y a un million d'idées de jeu là dehors, vous pouvez passer à un meilleur. » Vous pouvez voir dans l'histoire de Marble Blast à quel point peuvent être puissants les modèles de développement itératif pour produire rapidement des jeux de qualité. Marble Blast n'aurait jamais fonctionné aussi bien, sans cette approche générale pour développer un jeu. 26 / 223 Documentation de Torque V1.3.x 2.7 Conclusion Ainsi, vous avez appris tous nos secrets de développement de jeux ! Nous espérons que ce chapitre était utile. Si tout va bien, l'idée de créer un jeu ne semble pas être décourageante après avoir eu un aperçu du processus de base. Le conseil offert dans ce chapitre était de très haut niveau, car entrer dans les détails n'est pas la bonne voie pour commencer l'apprentissage. Il peut être difficile de savoir où commencer avec Torque, et de saisir ce que peut être le développement d'un jeu – il aide ainsi à avoir une vue d'ensemble. Maintenant, nous avons une idée générale du développement d'un jeu indépendant à succès, et pouvons commencer à creuser dans les outils de Torque : outils d'édition, possibilité de scripts, architecture du moteur, et des aspects artistiques. Comme discuté précédemment, il y a une multitude de ressources en dehors de ce livre permettant aussi d'apprendre. Dans le chapitre suivant, nous commencerons l'étude de l'outil d'édition d'interfaces graphiques (GUI editor) de Torque. 27 / 223 Documentation de Torque V1.3.x 3 Les éditeurs de Torque 3.1 Introduction à l'éditeur GUI Tous les jeux exigent, d'une manière ou d'une autre, une interface graphique utilisateur (GUI). Que ce soit un système de menus, un affichage tête haute (HUD15) ou une boîte de dialogue des options, chaque jeu nécessite des contrôles GUI pouvant recevoir des entrées de la part de l'utilisateur, et afficher des résultats d'une manière visuelle. Le TGE apporte un éditeur GUI intégré, une fonctionnalité que peu (s'il y en a) d'autres moteurs offre. Le système GUI de Torque est puissant et flexible. Il permet un contrôle précis de vos interfaces de jeux, et vous autorise presque toutes les interfaces que vous pouvez imaginer. Les GUI sont importantes car elles sont les interfaces qui seront constamment utilisées par les joueurs, toutes les fois qu'ils joueront. Bien souvent, votre menu GUI est la première chose que les joueurs voient dans un jeu. Une conception intuitive, et facile à utiliser des interfaces interagissant avec les joueurs est une partie majeure de la conception d'un jeu. La connaissance de l'utilisation de l'éditeur de GUI et de son complet potentiel est très importante pour le succès de votre jeu. 3.1.1 Qu'est-ce qu'une GUI ? Comme indiqué précédemment, une GUI est une interface graphique utilisateur. C'est l'addition de tous les contrôles (fenêtres, boutons, champs de texte, etc.) qui sont utilisés pour interagir avec un jeu et son paramétrage. La plupart des interfaces GUI dans les jeux sont constituées de boutons pour lancer ou rejoindre une session de jeu, de dispositifs d'édition pour modifier les préférences de l'utilisateur, d'options pour changer la résolution de l'écran et les options de rendu, et d'éléments qui affichent des données en cours de jeu pour l'utilisateur. Les deux copies d'écran ci-dessous sont des exemples de GUI en plein écran. Les images de fond, et tous les boutons et textes, sont créés comme contrôles GUI : Figure 15 Dans ce chapitre, nous verrons comment utiliser l'éditeur GUI intégré pour créer ce type d'écrans. Nos exemples de boutons et de contrôles sont simplistes, mais ne soyez pas dégouté. En suivant les leçons, vous apprendrez dans ce chapitre, qu'en adaptant la disposition et le graphisme de votre GUI, vous pouvez créer des GUI avancées et dynamiques avec presque tous les aspects et ressentis que vous désirez. 15 HUD : Abréviations de « Heads Up Display ». Il s'agit de l'ensemble des informations affichées sur l'écran (niveau de santé, munitions, armes...) 28 / 223 Documentation de Torque V1.3.x 3.1.2 Exploration de l'éditeur GUI Avant d'entrer dans les détails sur l'utilisation de l'éditeur GUI (GUI Editor), jetons un coup d'œil aux outils principaux qu'il offre. Vous pouvez ouvrir l'éditeur GUI de Torque en appuyant sur la touche F10 de votre clavier. Une fois que vous avez ouvert l'éditeur GUI, vous verrez un écran ressemblant à quelque chose comme la figure 16. Figure 16 En haut de l'éditeur GUI, on a la barre de menus. Ici, vous trouverez diverses fonctions utilitaires pour vous aider facilement à éditer des contrôles GUI. Le premier élément de la barre de menus est le menu déroulant File (Fichier) comme en figure 17. Il contient les options New GUI (création d'une nouvelle GUI), et Save GUI (sauvegarde de la GUI courante), ainsi qu'une option GUI Editot Help (Aide) et Toggle GUI Editor (sortie de l'éditeur GUI). Le second élément de la barre de menu est le menu déroulant Edit (Édition), comme montrer en figure 18. Ici, vous pouvez trouver les options Cut (couper), Copy (copier), Paste (coller) et une commande très pratique Select All (tout sélectionner), qui sélectionnera tous les contrôles GUI à la fois dans l'éditeur. Figure17 Figure 18 Le troisième élément sur la barre de menus est le menu déroulant Layout (disposition) comme en figure 19. Ce menu contient diverses actions vous permettant de déterminer la disposition et la position d'un contrôle GUI. Align Left (alignement à gauche), Align Right (alignement à droite), Align Top (alignement en haut), et Align Bottom (alignement en bas) vous aide à contrôler l'alignement de votre contrôle GUI, comme leurs noms le suggèrent. Les options Bring to front (amener au premier plan) et Send to Back (envoyer en arrièreplan) vous permettent de contrôler l'ordre de tracer des contrôles GUI. Le quatrième élément de la barre de menus est le menu Move (déplacer) comme montrer en figure 20. Ici, vous trouverez divers utilitaires pour vous aider à positionner plus précisément vos contrôles GUI. 29 / 223 Documentation de Torque V1.3.x Figure 20 Figure 19 Juste au-dessous de la barre de menus, il y a trois autres boutons/menus déroulants. Le premier à gauche, New Control (nouveau contrôle), comme en figure 21, créera de nouveaux contrôles GUI. Pour créer un nouveau contrôle, sélectionnez-en simplement le type dans la liste déroulante. Le second menu, au milieu et montré en figure 22, vous permet de basculer entre les fenêtres/collections GUI de contrôles précédemment sauvegardées. Pour finir, le troisième menu, à droite et montré en figure 23, vous permet de visualiser et d'éditer votre GUI dans différentes résolutions. Figure 21 30 / 223 Documentation de Torque V1.3.x Figure 22 Figure 23 Complètement à droite de l'éditeur GUI, il y a une longue colonne prenant toute la hauteur de l'écran, comme en figure 24. Ce rectangle contient l'arbre GUI (GUI Tree View) et la boîte d'inspection (Inspector Dialog). L'arbre GUI liste tous les contrôles de l'écran courant dans une liste hiérarchique. Cette liste vous aidera à sélectionner les divers contrôles que vous avez créés, ainsi qu'il visualise d'un coup d'œil quels contrôles sont les enfants d'autres contrôles. La boîte d'inspection est en dessous, et elle contient diverses options et propriétés suivant le type de contrôle GUI que vous avez sélectionné. Vous effectuerez la majeure partie, si ce n'est pas la totalité, de vos éditions ici. La plupart des options communes sont le profile – ce qui vous permet de définir à quoi ressemble un contrôle, ses actions et sa position – qui contient une série de valeurs délimitées par un espace décrivant où le contrôle est placé sur l'écran, et le champ extent – qui définit la taille du contrôle. La barre verticale à droite est déplaçable (voir figure 25) pour vous permettre d'exposer de plus d'espace de travail pour l'écran ou pour lire et éditer plus facilement l'arbre GUI et les champs de la boîte d'inspection. 31 / 223 Documentation de Torque V1.3.x Figure 24 Figure 25 3.1.3 Bases de l'éditeur GUI Maintenant que nous avons un premier aperçu de l'interface de l'éditeur GUI, prenons un moment pour en apprendre plus sur le placement, le déplacement et l'édition des propriétés d'un contrôle GUI. Le guide suivant vous mènera, pas à pas, au travers du processus de création d'un nouveau bouton de commande. 1. Créer un nouveau bouton graphique (Bitmap Button) en allant sur le bouton New Control et en sélectionnant GuiBitmapCuttonCtrl, comme en figure 26. Les boutons graphiques sont des boutons pouvant utiliser une image comme fond. Une fois que vous avez cliqué sur GuiBitmapCuttonCtrl, vous verrez le nouveau contrôle créé apparaître dans le coin supérieur gauche de l'écran. Il sera automatiquement sélectionné pour vous. Ainsi, le contrôle sera listé dans l'arbre GUI, sous MainMenuGui, car vous avez créé le contrôle dans la fenêtre qui définit le menu principal. En tant que tel, MainMenuGui est le parent, ou l'objet container de GuiBitmapCuttonCtrl. Les propriétés des contrôles parents peuvent aussi affecter les propriétés des contrôles qui y sont contenus. Par exemple, si la visibilité de MainMenuGui est initialisée à false, tous ses enfants seront aussi invisibles. Voir figure 27 et 28. 32 / 223 Documentation de Torque V1.3.x Figure 26 Figure 27 Figure 28 2. Avec le contrôle sélectionné nouvellement créé, cliquez et glissez le contrôle vers le centre de l'écran comme en figure 29. C'est une des méthodes pour déplacer des contrôles dans l'éditeur 33 / 223 Documentation de Torque V1.3.x GUI. Vous pouvez aussi déplacer des contrôles en utilisant le champ de position de l'inspecteur GUI (traité plus loin). Figure 29 3. Avec le contrôle toujours sélectionné, regardez le champ extent dans la boîte d'inspection sur la gauche. Changez la valeur « 110 20 ». Maintenant, cliquez le bouton Apply dans la boîte d'inspection et regardez les changements de votre bouton. La première valeur décrit l'extension du contrôle dans sa largeur, et la seconde valeur décrit l'extension du contrôle dans sa hauteur. Vous pouvez maintenant utiliser la souris pour saisir le bord du contrôle pour son dimensionnement. Voir figure 30. Figure 30 4. Toujours dans la boîte d'inspection, changez le champ Name en « My First Button » et cliquez sur le bouton Apply. Vous devez remarquer dans l'affichage GUI que votre nouveau contrôle indique « My First Button », comme le montre la figure 31. 34 / 223 Documentation de Torque V1.3.x Figure 31 5. Toujours dans la boîte d'inspection, cliquez sur le bouton Profile pour afficher une liste déroulante des contrôles de profil. Ces contrôles sont essentiellement des contrôles modèles, qui définissent, entre autres, comment apparaîtra et se comportera un contrôle particulier. Lorsque vous appliquez un profil à un contrôle, il prend les propriétés du profil. À partir de la liste des profils, sélectionnez GuiButtonProfile, comme en figure 32. Ensuite, éditez le champ texte avec « MyFirstBoutton » (sans les guillemets) et cliquez sur le bouton Apply. Vous noterez dans l'arbre GUI au-dessus que votre contrôle est maintenant nommé MyFirstButton. Voir figure 33. Figure 32 35 / 223 Documentation de Torque V1.3.x Figure 33 6. Une fois que vous avez réalisé les étapes précédentes, il est temps de placer le nouveau contrôle. Puisque les interfaces utilisateur sont très importantes pour conserver une audience intéressante, vous devez avoir un contrôle précis de placement de tous vos contrôles GUI. Nous pouvons réaliser ceci dans l'éditeur GUI de Torque en éditant les champs de position dans la boîte d'inspection. Modifiez ce champ en « 36 345 » (voir figure 34). Vous pouvez aussi glisser le contrôle à la position appropriée et utiliser les règles pour aligner votre bouton avec le reste des autres boutons, et alors utiliser le menu déroulant Move pour déplacer légèrement le contrôle dans une direction particulière. Essayez l'une ou l'autre des méthodes. Figure 34 7. À ce point, nous avons créé un bouton, l'avons libellé convenablement, lui avons donné un profil de bouton de commande approprié, et placé où nous le souhaitions sur l'écran. La prochaine étape consiste à faire que le bouton de commande effectue une action lorsqu'on clique dessus. Pour faire cela, nous entrerons une commande TorqueScript dans le champ Command du bouton. Si cela semble effrayant, ne vous inquiétez pas ; vous verrez que ce système est très simple à utiliser. Dans la boîte d'inspection, trouvez la zone de texte à côté du label command. Entrez le texte suivant dedans : « Canvas.pushDialog(HelloWord); » (sans les guillemets). Une fois que vous aurez saisi le texte, comme en figure 35, cliquez sur le bouton Apply. 36 / 223 Documentation de Torque V1.3.x Figure 35 8. Nous sommes proches de la fin, mais il y a un avertissement final que vous devrez prendre en compte avant que votre contrôle ne soit terminé. Si vous sortez de l'éditeur GUI maintenant en appuyant sur la touche F10, vous pouvez trouver que votre nouveau contrôle s'est déplacé, et qu'il n'est pas placé à la même position à laquelle vous l'aurez mis dans l'éditeur GUI, comme à la figure 36. Ceci arrive, car le contrôle n'a pas un alignement correct. Pour corriger cela, retournez dans l'éditeur GUI, sélectionnez le bouton que vous avez créé, et changez le vertSizing en « Top », comme en figure 37. Maintenant, cliquez sur Apply. En modifiant les options vertSizing ou horizSizing, vous indiquez à la GUI d'aligner le contrôle d'une manière particulière. Vous pouvez expérimenter ceci avec les diverses options d'alignement pour voir les effets qu'elles ont sur les contrôles. Le point principal à se rappeler dans cela est que, si vos contrôles ne sont pas à la bonne place lors de la fermeture de l'éditeur GUI, vous devrez modifier les options vertSizing et/ou horizSizing, afin que les contrôles soient correctement alignés sur un bord. Une fois que vous avez fait les ajustements d'alignement, il est temps de sauvegarder la GUI éditée. Figure 36 37 / 223 Documentation de Torque V1.3.x Figure 37 9. Afin que les modifications que nous avons effectuées dans le menu principal soient conservées lors du redémarrage de l'application Torque Demo, vous devez sauvegarder la GUI sur le disque. Pour cela, cliquez sur le menu File en haut de l'éditeur GUI, et cliquez sur l'option Save GUI, comme en figure 38. Dans la boîte de dialogue Save File qui apparaît, sélectionnez le fichier mainMenuGui.gui dans la liste des fichiers et, alors, cliquez sur Save comme montré en figure 39. Figure 38 38 / 223 Documentation de Torque V1.3.x Figure 39 10.Votre nouveau bouton devrait apparaître maintenant comme à la figure 40. Figure 40 À ce point, votre bouton ne fera actuellement rien lorsque vous cliquerez dessus. Nous avons donné au bouton un script de commandes lorsqu'il est cliqué, mais la commande que nous avons saisie n'aura aucun sens pour Torque tant que nous n'aurons pas suivi les étapes de la section suivante. Notre script de commande demande à Torque d'ouvrir un nouveau contrôle de dialogue appelé « HelloWorld », mais nous pas encore créé ce dialogue. Une fois que nous l'aurons fait, tout fonctionnera comme prévu ! 3.1.4 Création d'un nouveau dialogue Maintenant que nous avons passé un peu de temps sur les bases de l'éditeur GUI et avons créé un bouton de commande, nous créerons un nouveau dialogue pour les utilisateurs de votre jeu pour interagir avec eux. Ensuite, dans la section après cela, nous relierons ensemble le bouton que nous avons précédemment créé et le dialogue que nous sommes sur le point de créer pour vous montrer comment ces deux GUI séparées viennent ensemble pour créer une interface utilisateur. Pour commencer, ouvrez l'éditeur GUI et cliquez sur l'option File de la barre de menus, comme en figure 41. Dans la fenêtre de dialogue qui apparaît, tapez « HelloWolrd » dans le champ GUI Name et cliquez sur le bouton Create, comme en figure 42. Après cela, vous aurez un nouvel écran d'édition GUI, comme en figure 43. 39 / 223 Documentation de Torque V1.3.x Figure 41 Figure 42 Figure 43 Vous avez maintenant un écran vierge pour travailler. La première chose à faire est de créer un nouveau contrôle GUI avec lequel votre utilisateur peut interagir. Sinon, nous finirons avec un tas de problèmes si 40 / 223 Documentation de Torque V1.3.x nous poussons cet écran sur le canvas et qu'il n'a pas de contrôle. Allez sur le bouton New Control en haut et sélectionnez GuiWindowCtrl dans la liste déroulante, comme en figure 44. Figure 44 Lorsque le nouveau contrôle apparaît, glissez-le et dimensionnez-le, afin qu'il ressemble au contrôle de la figure 45. Trouvez le champ text dans la boîte d'inspection et entrez « Canvas.popDialog(HelloWorld); » (sans les guillemets). Maintenant, cliquez sur Apply. Figure 45 Maintenant que vous avez décidé à quoi vous voulez que votre fenêtre de dialogue ressemble, il est temps de placer un autre contrôle sur la fenêtre. Lorsque nous avons créé le contrôle-fenêtre, c'était une partie du canvas. Maintenant, lorsque nous créons un autre contrôle, nous voulons qu'il soit un enfant de notre contrôle-fenêtre, au lieu du canvas lui-même. Faire d'un nouveau contrôle un enfant de la fenêtre de dialogue que nous venons juste de créer, forcera le nouveau contrôle de se placer dans le contrôle-fenêtre. Pour réaliser ceci, cliquez avec le bouton droit sur votre contrôle-fenêtre. Ensuite, vous remarquerez qu'une petite ligne jaune encadrera votre contrôle. Cela signifie que le contrôle a le focus de l'éditeur GUI. Tant qu'il a le focus, tous les nouveaux contrôles que nous ajoutons dans l'éditeur GUI deviendront des enfants du contrôle-fenêtre de dialogue, héritant de ce fait de sa position, sa visibilité, et d'autres propriétés. Voir figure 46. 41 / 223 Documentation de Torque V1.3.x Figure 46 Avec votre contrôle-fenêtre ayant encore le focus, allez sur le bouton New Control en haut de l'éditeur GUI et sélectionnez GuiTextCtrl dans la liste déroulante. Glissez et positionnez le nouveau contrôle vers le centre de votre fenêtre-dialogue. Ne vous inquiétez pas du positionnement du contrôle exactement au centre du dialogue, nous laisserons l'éditeur GUI faire cela pour nous. Dans la boîte d'inspection, positionnez horizSizing et vertSizing sur « Center ». Pour finir, saisissez « Hello World » dans le champ text. Cliquez sur Apply. Voir figure 47 pour plus de détails. Figure 47 Avant que nous continuions avec la section suivante, vous devez sauvegarder votre nouvelle GUI, ainsi vous pouvez sortir de l'éditeur GUI sans craindre de perdre votre travail. Pour sauvegarder votre nouveau contrôle, cliquez sur le menu File et choisissez l'option Save GUI. Dans la boîte qui apparaît, tapez « HelloWord.gui » (sans les guillemets). Modifiez aussi le répertoire en « starter.fps/client/ui » en haut, et cliquez sur Save. Tout cela est dans la figure 48. 42 / 223 Documentation de Torque V1.3.x Figure 48 Maintenant que votre nouvelle GUI est sauvegardée, nous retournerons au MainMenuGui. Cliquez sur le bouton central en haut de l'éditeur GUI et sélectionnez MainMenuGui dans la liste déroulante, comme en figure 49. Figure 49 À ce point, vous devez sortir de l'éditeur GUI en appuyant sur la touche F10, puis fermer l'application Torque Demo. 3.1.5 Mettre tout ensemble Maintenant que vous avez créé et sauvegardé votre nouveau contrôle GUI ainsi que votre nouveau bouton, nous allons les lier ensemble et créer un bouton cliquable qui lancera votre fenêtre Hello World ! Afin de faire cela, nous devons dire au moteur que nous utilisons un nouvel élément GUI. Pour que cela fonctionne, nous aurons à ajouter une simple ligne à un certain code de script. Pour ajouter ce code de script, premièrement parcourez le répertoire où est installé le SDK de Torque. Une fois là, allez dans « example\starter.fps\client ». Par exemple, si votre copie du SDK de Torque est installée dans C:\, allez dans « C:\torque\example\starter.fps\client ». Voir la figure 50 pour un exemple. 43 / 223 Documentation de Torque V1.3.x Figure 50 Maintenant, trouvez et ouvrez le fichier « init.cs » dans votre programme d'éditeur de texte favori. La copie d'écran ci-dessous utilise jEdit. Une fois que vous avez ouvert le fichier, recherchez le bloc de code commençant par le commentaire : // Load up the shell GUIs. Ceci est montré en figure 51. Figure 51 Juste après la dernière ligne de ce bloc de script, entrez la ligne de code suivante : Exec("./ui/HelloWorld.gui"); Il est extrêmement important que vous saisissiez la ligne précédente exactement comme indiqué. Sinon, la compilation du fichier de script échouera. Voir figure 52 pour des détails. 44 / 223 Documentation de Torque V1.3.x Figure 52 L'ajout de la ligne précédente indique à Torque que nous utilisons un nouvel élément GUI, qu'il doit le charger. Une fois que vous êtes certain d'avoir entré correctement le code, vous pouvez maintenant sauvegarder le fichier « init.cs » modifié et fermer votre éditeur de texte. Maintenant, chargez à nouveau l'application Torque Demo. Une fois le menu principal chargé, cliquez sur le bouton MyFirstButton que vous avez créé. Lorsque vous faites cela, votre dialogue Hello World devrait apparaître. Si le dialogue n'apparaît pas, assurez-vous soigneusement que vous avez correctement suivi les étapes de ce chapitre, et saisissez le code exactement comme il est présenté. Tout fonctionnera si vous avez fait cela. Félicitations pour la création de vos premiers contrôles GUI ! Figure 53 3.1.6 En résumé Dans ce chapitre, nous avons eu une introduction sur l'éditeur GUI de Torque, une des fonctionnalités uniques du moteur. Nous avons créé des contrôles très simples, mais l'éditeur GUI peut être utilisé pour créer des interfaces utilisateur avancées et ayant une belle apparence. À ce point, vous devriez avoir une connaissance de base du fonctionnement général de l'éditeur GUI. À partir d'ici, vous pouvez expérimenter et « jouer » en créant divers éléments GUI, et en leur assignant divers profils et propriétés. Suivez les étapes de ce guide toutes les fois que vous créerez un contrôle, en les adaptant à 45 / 223 Documentation de Torque V1.3.x votre situation particulière, et vous commencerez la création de quelques trucs amusants en un rien de temps. 3.2 Introduction à l'éditeur de mission 3.2.1 Aperçu des éditeurs de Torque Torque inclut de base deux éditeurs, l'éditeur de mission et l'éditeur GUI. L'éditeur de mission est décomposé en huit outils. Dans les pages suivantes, j'utiliserai des noms courts pour les outils individuels partout où il n'y aura pas d'ambiguïté. Table 1 Éditeurs Raccourcis Description Éditeur de mission F11 Cet éditeur est constitué de huit sous éditeurs, chacun vous permettant de modifier et sauvegarder divers aspects d'une mission spécifique. Cet éditeur peut être utilisé pour éditer des missions existantes ou pour en créer de nouvelles. Éditeur GUI F10 Cet Éditeur vous permet de modifier des GUI existantes ou d'en créer de nouvelles, en utilisant le glisser-déposer sur une interface simple Table 2 Outils Raccourcis Description Éditeur de monde F2 Cet outil vous permet de déplacer, de tourner et de changer l'échelle des objets ayant déjà été placés dans le monde. Inspecteur de l'éditeur de monde F3 En plus de fournir toutes les possibilités de l'éditeur de monde, cet éditeur vous permet de voir et de modifier les propriétés des différents objets des missions. Créateur de l'éditeur de monde F4 En plus de fournir toutes les possibilités de l'éditeur de monde, cet outil vous permet de placer de nouveaux objets dans la mission courante. Éditeur de zone de mission F5 Cet outil vous permet d'ajuster les frontières de la mission courante aussi bien que de retourner le terrain courant. Éditeur de terrain F6 Cet outil vous permet d'ajuster manuellement la hauteur de la carte de la mission aussi bien que de définir si des portions de carte « existent ». Éditeur de terraformation16 de terrain F7 En plus de fournir toutes les possibilités de l'éditeur de terrain, cet éditeur vous permet de charger une image en tant que fichier de terrain aussi bien que d'appliquer divers algorithmes de filtre sur le terrain. Éditeur de texture de terrain F8 En plus de fournir toutes les possibilités de l'éditeur de terrain, cet outil vous permet de sélectionner n'importe quel nombre de textures et de les appliquer en utilisant un jeu d'algorithmes pour en déterminer la combinaison et le placement. Peinture de texture de terrain Menu Windows -> Terrain Texture Painter En plus de fournir toutes les possibilités de l'éditeur de terrain, cet outil vous permet de sélectionner et d'appliquer jusqu'à 6 textures différentes sur le terrain. 3.2.2 Les outils de l'éditeur de mission 16 Issue de la science-fiction, la terraformation est devenue une science étudiant la transformation de l'environnement naturel d'une planète, d'une lune ou d'un autre corps, afin d'y réunir les conditions permettant une vie de type terrestre, espérant donc la rendre habitable par l'Homme. Le terme officiel en français est écogenèse.(Wikipédia) 46 / 223 Documentation de Torque V1.3.x Abordons d'abord le jeu d'outils de l'éditeur de mission, il a le plus de composants et est l'endroit le plus approprié pour commencer un simple MOD17 ou un nouveau jeu. Comme nous étudions et apprenons comment utiliser chacun des outils de l'éditeur de mission, veuillez utilisez la mission Basic Training comme mission courante. Avant que vous expérimentiez avec les Éditeurs sur n'importe quelle mission existante, vous devriez en faire une copie d'abord. Le moyen le plus facile pour faire ceci (pour le moment) est de créer une copie de la totalité du répertoire egt/missions. Veuillez effectuer cela avant de poursuivre. 3.2.2.1 Bases de l'éditeur de mission Avant de plonger dans les outils de l'éditeur de mission, passons en revue quelques bases qui resteront vraies pour l'ensemble des outils, notamment les éléments de l'interface utilisateur. Plus tard, nous discuterons des mécanismes de mouvement et du contrôle du point de vue, aussi bien que de la sélection, du déplacement, de la rotation et de la mise à l'échelle d'un objet. 3.2.2.1.1 Éléments de l'éditeur de monde Dans ce guide, je fais référence aux curseurs, aux menus et à d'autres éléments graphiques que vous rencontrerez dans les éditeurs comme Devices. Indiqués simplement, ces éléments vous fournissent des informations importantes sur les actions pouvant être ou devant être prises. Les termes ci-dessous sont la plupart du temps de ma propre invention hormis le nom gizmo (truc/machin). 3.2.2.1.1.1 Curseurs Table 3 : curseurs Type de curseur Curseur Description Curseur de non-sélection Lorsque le curseur ressemble à ceci, cela signifie que le curseur n'est pas au-dessus d'un objet sélectionnable. En d'autres mots, vous pointez sur une zone vide. Curseur de sélection Lorsque le curseur ressemble à ceci, cela signifie que le curseur est au-dessus d'un objet sélectionnable. Curseur de saisie Lorsque le curseur ressemble à ceci, cela signifie que vous avez sélectionné un ou des objets et que vous maintenez appuyé le bouton gauche de la souris. Vous avez saisi le ou les objets. Curseur de rotation/d'échelle Lorsque le curseur ressemble à ceci, cela signifie que vous avez sélectionné avec succès un axe du gizmo en mode rotation ou changement d'échelle. Il apparaît aussi lorsque vous avez sélectionné avec succès une face d'une boîte d'encadrement pour un changement d'échelle. 3.2.2.1.1.2 Le gizmo Table 4 : le gizmo et les échelles de gizmo 17 Un MOD est une version modifiée d'un jeu, par exemple, les personnages ont été changés, ainsi que les décors, les cartes... Cette possibilité est souvent prévue par les concepteurs de jeux, afin d'allonger la durée de vie de leurs créations, mais elle est généralement détournée anarchiquement par les fans. 47 / 223 Documentation de Torque V1.3.x Description Élément Le dessin sur la droite représente le gizmo. Les éléments suivants montreront le gizmo en action, mais pour le sujet de discussion, cette représentation sera plus simple pour en parler. Le gizmo est un élément qui est activé lorsque vous sélectionnez un ou plusieurs objets. Il affiche trois axes X-Y-Z traditionnels. Les axes individuels sont sélectionnables et offrent la possibilité de déplacer, tourner ou mettre à l'échelle. Par défaut, un axe-gizmo est cyan sombre lorsqu'il n'est pas sélectionné et cyan clair lorsque le curseur est au-dessus de lui ou lorsqu'il a été saisi. Cette échelle montre la position courante du barycentre de l'objet lorsque vous utilisez le gizmo pour déplacer un objet. Échelle de translation gizmo Cette échelle montre le degré de rotation courant autour de l'axe sélectionné lorsque vous utilisez le gizmo pour tourner un objet. Échelle de rotation gizmo Cette échelle montre la hauteur, la largeur et la profondeur courantes d'un objet lorsque vous utilisez le gizmo pour en modifier l'échelle. (w,h,d) correspond aux axes (x,y,z) du gizmo. Échelle de modification d'échelle gizmo 3.2.2.1.1.3 Menus et fenêtre Table 5 : menus et fenêtres Description Élément L'éditeur de monde fournit un jeu de menus traditionnels pour la sélection de l'outil courant aussi bien que d'autres fonctionnalités. Je couvrirai toutes les options dans les menus de l'éditeur de monde. Menus de l'éditeur de monde 48 / 223 Documentation de Torque V1.3.x Description Élément Plusieurs des outils ont des fenêtres qui apparaissent sur le côté droit de l'écran. Bien que ces fenêtres aient beaucoup de similarités, ce sera mieux si je les explique individuellement. Je ferai cela dans les sections sur les outils plus loin. La partie inférieure de la fenêtre montrée ci-contre vient de la version principale et est légèrement différente de la version 1.1.2 et des versions antérieures. Dans la 1.1.2 et avant, tous les champs et boutons sont dans le même bloc, ce qui rendait la lecture ou recherche parfois un peu difficile. 3.2.2.1.1.4 Boîte de sélection Table 6 : boîte de sélection Description Élément Lors de la sélection d'un objet précédemment non sélectionné, le curseur de sélection vous fait savoir lorsque vous pouvez sélectionner quelque chose, et la boîte de sélection (verte) montre que l'objet précédemment non sélectionné sera sélectionné. Une fois que vous avez sélectionné avec succès un objet, l'objet sera affiché avec une boîte de sélection rouge et une boîte de sélection jaune. La boîte rouge sert à l'alignement avec les objets, tandis que la boîte jaune sert à l'alignement avec le monde. Le but de la boîte jaune est de montrer quels sont les objets étant sélectionnés comme un groupe et qui seront affectés par toutes les actions que vous effectuerez. Les boîtes rouges servent à montrer quels objets individuels dans la boîte de sélection du groupe font partie actuellement de la sélection. Notez que dans l'image ci-contre, les personnages de gauche et de droite sont sélectionnés, tandis que celui du milieu n'y est pas. 49 / 223 Documentation de Torque V1.3.x Description Élément Une fois que vous avez sélectionné avec succès un objet, l'objet avec une boîte de sélection passera au bleu si votre curseur passe dessus. Note : ceci n'est pas vrai pour le sélectionner-glisser 3.2.2.1.1.5 La poignée et la grille de niveau Table 7 : la poignée et la grille de niveau Élément Poignée sélectionnée Poignée non sélectionnée Description Chaque objet dans le monde affiche une poignée. La poignée a deux labels près d'elle : • Un nombre – indiquant le numéro de l'objet dans la liste des objets de la mission. • Un nom – si ce nom est (null), aucun nom n'a été assigné à cet objet. Les noms sont optionnels, mais très utiles lors de l'utilisation de scripts. Lorsque qu'un objet est sélectionné, une faible grille apparaîtra. La grille est parallèle au plan X-Y du monde et traverse l'objet sélectionné en passant par la poignée. Lorsque de multiples objets sont sélectionnés, le plan passe au travers de la poignée du groupe qui est situé au point de croisement des axes du groupe gizmo. 3.2.2.1.1.6 Éléments d'échelle Table 8 : éléments d'échelle Description Élément Vous verrez cet élément lors de l'édition de terrain et de l'ajustement des paramètres du terrain. Le fonctionnement de cet élément est simple. L'échelle 2D (ligne avec les points rouges) représente un paramètre en deux dimensions. En fonction de l'application, l'espacement horizontal peut représenter une élévation, un angle, etc. L'espace vertical peut représenter une opacité, un facteur de mélange (de textures), la force d'une action, etc. Les points rouges sur la ligne sont les points de contrôles. Ces points ne peuvent être déplacés que verticalement. Toutes les interfaces d'échelle présentent une boîte d'incrémentation pour ajouter ou retirer des points de contrôle, augmentant de ce fait la résolution horizontale. 50 / 223 Documentation de Torque V1.3.x 3.2.2.1.2 Mécanismes de l'éditeur de monde Maintenant que nous nous sommes familiarisés avec les divers éléments disponibles dans l'éditeur de mission, discutons des mécanismes de la façon dont nous manipulons les objets dans la mission en utilisant la souris. Nous parlerons des déplacements dans la mission, du basculement des modes de caméra et des points de vue, de la sélection des objets et l'utilisation de la souris pour manipuler les positions, les rotations, et les échelles via le gizmo. 3.2.2.1.2.1 Mouvement et point de vue par défaut Table 9 : mouvement et point de vue par défaut Élément Déplacement Description W, A, S, D, barre d'espace (haut, gauche, bas, droit, saut) Vue + déplacement de la souris Zoom E Point de vue de base du personnage Tab (en mode jeu seulement) Bascule entre : vue première personne et vue troisième personne Caméra Alt + C Bascule entre : vue du personnage courant et caméra libre Vitesse de mouvement de caméra Majuscule + 1 – Majuscule + 7 (plus lent – plus rapide) Lorque le point de vue de la caméra est sélectionné, vous pouvez ajuster la vitesse de déplacement de la caméra n appuyant sur la touche Majuscule et une touche de chiffre. « Lâché » de joueur à la position de F7 (seulement en mode jeu) la caméra Alt + W (mode éditeur de mission seulement) Ctrl + F7 (mode éditeur de mission OU mode jeu) « Lâché » de caméra à la position du Alt + Q (mode éditeur de mission seulement) personnage 3.2.2.1.2.2 Sélection et déplacement d'objet Table 10 : sélection et déplacement d'objet 51 / 223 Documentation de Torque V1.3.x Élément Description (Dé)Sélection d'objet : Sélectionne des objets Majuscule + : Sélectionne des objets (si les objets ne sont pas déjà sélectionnés), désélectionne des objets (si les objets sont déjà sélectionnés) (sur un emplacement vide) + glisser : Sélectionne des objets dans le cadre. Note : le cadre de sélection à besoin d'inclure les poignées des objets (indiquées par les points rouges) Déplacement d'objet (sans utilisation de gizmo) + glisser : déplace un ou des objets sélectionnés. 3.2.2.1.2.3 Utilisation du gizmo Comme décrit au-dessus, le gizmo est l'appellation de la représentation des trois axes qui apparaît lorsque vous sélectionnez soit un objet, soit un groupe d'objets. Le gizmo a trois poignées sélectionnables individuellement alignées sur les axes X, Y et Z. Ces poignées vous donnent la possibilité de déplacer, de tourner et de dimensionner des objets. Les déplacements et rotations gizmo peuvent être appliqués sur un objet seul sélectionné ou sur de multiples objets sélectionnés. Les rotations se font toujours par rapport à la poignée de l'axe gizmo choisi pour l'objet sélectionné ou le groupe d'objets sélectionnés. La modification d'échelle gizmo ne peut être appliquée que sur un seul objet sélectionné. Table 11 : utilisation des Gizmo 52 / 223 Documentation de Torque V1.3.x Élément Description Déplacement (sur l'axe gizmo) Glisser à gauche/à droite pour les axes X et Y, et en haut/en bas pour l'axe Z. Majuscule + Gizmo d'objet simple (sur l'axe gizmo) Glisser à gauche/à droite pour les axes X et Y, en haut/en bas pour l'axe Z. Gizmo aligne sur les axes du monde et confine le déplacement le long de l'axe du monde sélectionné. Rotation Alt + (sur l'axe gizmo) Glisser à gauche/à droite Dimensionnement (objet seul uniquement) Ctrl + Alt + Gizmo d'objets multiples (sur l'axe gizmo) Glisser à gauche pour augmenter et à droite pour diminuer 3.2.2.1.2.4 Dimensionnement par utilisation des côtés des boîtes d'encadrement Lors de l'expérimentation, j'ai accidentellement découvert qu'il y avait une autre méthode pour dimensionner des objets avec la souris. Non seulement cette méthode est plus intuitive, mais elle ne requiert pas l'utilisation du gizmo. Essayez ceci : 1. 2. 3. 4. Désélectionnez tous les objets Trouvez l'objet que vous souhaitez dimensionner et sélectionnez-le. Maintenez appuyée la combinaison : Ctrl + Alt Cliquez sur un des côtés de la boîte d'encadrement de l'objet et déplacez la souris pour dimensionner l'objet. Vous remarquerez que le côté sélectionné devient bleu tout en restant transparent Et c'est tout ce qu'il y a à faire ! L'image ci-dessous montre une face sélectionnée de la boîte d'encadrement. 3.2.2.2 Éditeur de monde (le manipulateur) Lancement du manipulateur (Manipulator) 53 / 223 Documentation de Torque V1.3.x 1. Lancez l'éditeur de mission en appuyant sur F11 2. Lancez le manipulateur en appuyant F2 3.2.2.2.1 La fenêtre de visualisation du monde 3D Le bénéfice réel du manipulateur provient du fait que vous pouvez traverser le monde, et la vue du monde 3D n'est pas gênée par des dialogues ou menus (excepté par ceux de l'éditeur de mission), vous donnant presque une vue plein-écran pendant que vous manipulez des objets via la souris et les raccourcis. Après examen, on peut voir que cet outil est clair, certainement comme prévu. Dans l'exemple vu précédemment, nous pouvons voir le monde et ses contenus. Nous pouvons appliquer toutes les manipulations standards comme décrit dans le chapitre « Bases de l'éditeur de mission ». 3.2.2.2.2 Menus de l'éditeur de monde Tous les outils de l'éditeur de monde ont un menu contenant les mêmes éléments. Cependant, dans quelques outils, certains menus seront désactivés. Les tables suivantes vous donnent un bref aperçu de chaque menu et des options de ceux-ci. Quelques descriptions d'options seront abordées plus tard lorsque nous discuterons spécifiquement de l'outil affecté par l'option citée. 3.2.2.2.2.1 Menu File Table 12 : menu File Élément Description New mission (nouvelle mission) La sélection de cette option générera une nouvelle mission basée sur les valeurs prédéfinies pouvant être trouvées dans exemples\egt\data\newmission.mis. Cela génère la même mission à chaque fois. Ceci entraîne l'effacement de la mission en cours. Ceci devra être fait une fois, et une seule, avant l'édition. Open Mission (ouvrir mission) – Ctrl+O Affiche un dialogue vous permettant de charger une mission existante. Actuellement, je vous suggère de ne pas utiliser cette méthode pour passer d'une mission à l'autre lors de l'édition. À la place, je vous suggère d'éditer qu'une seule mission par session (par exécution du SDK). Save Mission (sauvegarder mission) – Ctrl+S Ceci sauvegarde votre mission courante. Save Mission As (sauvegarder mission comme...) Comme pour Save Mission, ceci vous permet de sauvegarder votre mission, mais dans ce cas, vous pouvez spécifier un nom et un emplacement existant pour le fichier de mission. Import Terraform Data (import des données de terraformation) Cette option vous permet de charger des données de terraformation à partir d'une autre mission. Simplement, ceci remplace la carte d'élévation par celle de la mission choisie. Les textures du terrain restent inchangées. 54 / 223 Documentation de Torque V1.3.x Élément Description Import Texture Data (importation des données de texture) Cette option doit vous permettre de charger les données de texture à partir d'une autre mission, mais malheureusement, cela ne fonctionne pas. Export Terraform Bitmap (exportation de l'image de terraformation) Cette option est validée par l'outil Terraformer. Nous en discuterons plus tard. 3.2.2.2.2.2 Menu Edit Table 13 : menu Edit Élément Description Undo (annuler) – Ctrl+Z Annule la dernière opération. Ceci n'annule pas toutes les opérations, donc sauvegardez souvent. Redo (refaire) – Ctrl+R Refait la dernière opération. Comme pour undo, ceci ne s'applique pas à toutes les opérations. Cut (couper) – Ctrl+X Fonction standard copiant un ou des objets dans le presse-papier, mais supprimant ces objets originaux. Copy (copier) – Ctrl+C Fonction standard copiant un ou des objets dans le presse-papier. Paste (coller) – Ctrl+V Fonction standard collant un ou des objets présents dans le presse-papier. Select All (tout sélectionner) – Ctrl+A Sélectionne tous les objets (formes et intérieurs) de la mission. Select None (délectionner tout) – Ctrl+N Désélectionne tous les objets (formes et intérieurs) de la mission. Relight Scene (mise à jour Impose au moteur de mettre à jour l'éclairage du terrain courant et applique les de l'éclairage de la scène) cartes d'ombrage. Ceci gêne beaucoup de débutants. Je parlerai de ceci plus loin lorsque nous discuterons de l'ajout des intérieurs. Word Editor Settings (paramétrage de l'éditeur de monde) Ceci affiche la boîte de dialogue du paramétrage de l'éditeur de monde (discuté plus loin). Terrain Editor Settings (paramétrage de l'éditeur de monde) Cette fonctionnalité est liée à l'éditeur de terrain et sera abordée plus loin. 55 / 223 Documentation de Torque V1.3.x 3.2.2.2.2.3 Menu World Editor Settings Table 14 : paramètres de l'éditeur de monde Élément Description Render Plane (plan de positionnement) Montre un plan horizontal passant par l'origine d'un objet sélectionné Render Plane Hashes (grille du plan de positionnement) Montre un quadrillage passant par l'origine d'un objet sélectionné Render Object Text (texte Montre l'ID et le nom d'un objet sélectionné d'objet) Render Object Handle (poignée d'objet) Montre la poignée (rouge) au centre d'un objet sélectionné Render Selection Box (boîte de sélection) Montre la boîte de sélection d'un objet Plane Extent (taille du plan Taille du plan de positionnement (ce plan est carré) de positionnement) Grid Size (taille de grille) Taille de la grille du plan de positionnement (X Y Z) Show Mouse Popup Info (informations de souris) Affiche les informations de position (X Y Z), de dimensionnement (W H D) ou de rotation (X Y Z A) lors du déplacement de souris sur un objet sélectionné Move Scale (incrément de Sensibilité de la souris pour le déplacement des objets déplacement) Rotate Scale (incrément de rotation) Sensibilité de la souris pour la rotation des objets Scale Scale (incrément de Sensibilité pour le dimensionnement des objets dimensionnement) Planar Movement (mouvement planaire) Actif : Limite le déplacement des objets au plan de positionnement Inactif : L'objet tente de suivre le terrain lorsqu'il est déplacé (cela ne semble pas fonctionner). Cela ne s'applique pas au glisser du gizmo vertical Collide With Object's Bounding Box (collision avec les boîtes des sélections des objets) Les objets peuvent être sélectionnés en plaçant le curseur n'importe où sur la boîte de sélection. Remarque : cela ne fonctionne pas. Si cette option est déactivée, seul le dimensionnement via Ctl+Alt ne fonctionne plus 56 / 223 Documentation de Torque V1.3.x Élément Description Objects Use Box Center (les objets utilisent le centre des boîtes) Si actif, la poignée de l'objet est au centre, sinon elle est à la limite inférieure de la boîte de sélection Axis Gizmo Active (axes cizmo actifs) Montre les axes gizmo Min Scale Factor (facteur d'échelle minimal) Facteur de multiplication minimal avec lequel l'objet sera redimensionné par rapport à la dimension originale Max Scale Facor (facteur d'échelle maximal) Facteur de multiplication maximal avec lequel l'objet sera redimensionné par rapport à la dimension originale Visible Distance (distance Distance minimale à laquelle les poignées des objets sont visible) visibles/sélectionnables. Ceci n'a rien à voir avec la distance de visibilité durant le jeu. Examinez l'objet Sky (ciel) pour cela. Gizmo Screen Len (longueur du gizmo) Longueur des axes gizmo en points écran Project Distance (distance Longueur du rayon à laquelle le curseur de sélection est actif du projet) 3.2.2.2.2.4 Paramètres de l'éditeur de monde (astuces d'édition) Les paramètres de ce dialogue très compact servent à vous assister lors de l'édition d'une mission. Leur but principal est de vous simplifier la vie, le plus possible. Pour cela, voici quelques problèmes communs d'édition et leurs solutions : Table 15 : paramètres de l'éditeur de monde (astuces d'édition) Problème Solution Difficulté de placement Ajustez l'extension du plan de positionnement à deux fois la distance désirée d'objets à une distance (distance à partir du barycentre/poignée). Ensuite, réglez la taille de la grille au donnée de chacun d'eux. dixième de la distance désirée. Maintenant, vous pouvez utiliser la grille comme une règle. Exemple : si vous souhaitez placer un objet à 0,9 mètre d'un autre : 1. Plane Extent = 2 2. Grid Size = 0.1 0.1 0.1 Il y a trop de labels visibles 1. Désactivez Render Object Text (bien) 2. Réduisez Visible Distance (meilleur) Difficulté à dimensionner Exemple : si vous souhaitez dimensionner un objet à 2,75 fois de sa taille avec précision d'origine : Min Scale Factor = 1.0 Max Scale Factor = 2.75 Dimensionnez l'objet à exactement 2,75 ! Vous avez sélectionné accidentellement des objets lointains 1. Réduisez Project Distance (bien) 2. Réduisez Visible Distance (meilleur) Vos éléments passent au 1. Désactivez Planar Movement travers du terrain lorsque 2. Désactivez Objects Use Box Center vous les glissez Vos éléments devraient maintenant suivre le terrain lorsque vous les glissez. 3.2.2.2.2.5 Menu World 57 / 223 Documentation de Torque V1.3.x Table 16 : Menu World Élément Description Lock Selection (verrouillage de la sélection) Déactive les actions de la souris (déplacement, rotation, dimensionnement) sur les sélections courantes. Ceci n'interdit pas les modifications via la fenêtre d'inspection, cependant un cadenas indiquera le verrouillage dans l'arbre d'édition. Unlock Selection (déverrouillage de la sélection) Réactive les actions de la souris sur les sélections courantes. Hide Selection (masquage Cache les sélections courantes. En fait, cela désactive le rendu. de la sélection) Show Selection (montre la Montre les objets précédemment cachés sélection) Utilisez l'inspecteur pour sélectionner ces objets. Ils ont un petit œil devant eux dans l'arbre d'édition. Delete Selection Destruction des sélections courantes. (destruction de la sélection) Camera to Selection (caméra sur la sélection) Déplace la caméra au barycentre des sélections courantes. Reset Transforms (remise • à zéro des transformées) Annule la rotation des objets sélectionnés (aligne les objets sur l'alignement par défaut). • Annule le redimensionnement des objets sélectionnés (ramène la taille des objets à 100% de leur taille originale). Ceci est différent de Undo. Drop Selection (lâché de la sélection) Les objets sélectionnés tombent conformément aux règles courantes (voir plus loin) Ceci peut être la cause de la remontée à la surface d'objets souterrains. Add Selection to Instant Group (ajout de la sélection au groupe immédiat) Nous discuterons de cette fonctionnalité lorsque nous aborderons l'inspecteur. Drop at Origin (lâché à l'origine) Les nouveaux objets ou les objets collés seront créés à l'origine du monde. 58 / 223 Documentation de Torque V1.3.x Élément Description Drop at Camera (lâché à la caméra) Les nouveaux objets ou les objets collés seront créés à la position courante de la caméra. Vous pouvez penser à l'existence de trois caméras. 1. Une dans la tête du personnage durant la vue en mode première personne (1st POV) 2. Une seconde est la caméra suiveuse durant la vue en mode troisième personne (3rd POV) 3. Et, la troisième étant la caméra flottant librement Voici une image pour expliciter cela pour le mode 1st POV et 3rd POV. Drop at Camera w/Rot (lâché à la caméra avec rotation) Réalise la même chose que Drop at Camera, mais effectue en plus une rotation de l'objet pour que celui-ci soit parallèle à la caméra. Drop below Camera (lâché Dans ce mode, les nouveaux objets sont créés quelque part en dessous de la sous la caméra) caméra. Drop at Screen Center C'est le mode drop par défaut. Je pense que le nom de ce mode est impropre. (lâché au centre de l'écran) Bien que je n'ai pas regardé le code (honte à moi), il semble qu'il en fait plus : 1. Lancé de rayon à partir de l'œil de la caméra 2. Lors d'une collision avec la boîte de sélection d'un objet, avec de l'eau, ou avec le terrain, lâche l'objet au point de collision. 3. Si le rayon dépasse la Project Distance (boîte de paramétrage de l'éditeur de monde), lâche l'objet à la position de l'œil de la caméra. Drop at Centroid (lâché au Ceci est une option de positionnement très utile. Elle vous permet de barycentre) sélectionner plusieurs objets et place les nouveaux objets créés au barycentre virtuel du groupe. Drop to Ground (lâché au sol) La documentation officielle n'est pas claire là-dessus, mais ma première impression sur ce mode fut que l'objet devait tomber sur le sol au-dessous de la caméra. Manque de chance, les objets sont lâchés sur le sol à l'emplacement de l'objet copié. Je n'utiliserai donc pas ceci, s'il n'y a aucune possibilité de contournement interne de ce fait. 3.2.2.2.2.6 Menu Window Ce menu est probablement le plus facile à comprendre. Il vous permet de sélection l'outil de l'éditeur de mission que vous allez utiliser. La seule chose importante à se rappeler est que vous devez utiliser ce menu pour sélectionner l'outil de coloriage de textures de terrain (Terrain Texture Paint) puisqu'il ne possède pas de raccourci clavier. 3.2.2.3 Éditeur de monde (l'inspecteur) Lancement du manipulateur (Inspector) 59 / 223 Documentation de Torque V1.3.x 1. Lancez l'éditeur de mission en appuyant sur F11 2. Lancez l'inspecteur en appuyant F3 3.2.2.3.1 Examen de l'inspecteur L'outil d'inspection vous permet de sélectionner un objet et de manipuler tous ses paramètres de script via des boîtes de texte, des menus déroulants, des boutons radio, des cases à cocher, etc. Ces paramètres varieront suivant l'objet. Plus loin dans ce guide, nous examinerons les paramètres spécifiques pour l'eau, le terrain, le personnage, le ciel, etc. Maintenant, dans le but d'apprentissage de cet outil, nous travaillerons avec un objet très simple, appelé SpawnSphere. Pour le moment, le but de cet objet n'est pas important. La chose clef est qu'il est facile à placer et à manipuler. Pour commencer, regardez directement en l'air. Vous devriez voir un objet gris. Sélectionnez-le et vous devriez avoir une vue similaire à ceci : Faisons un inventaire rapide des éléments à l'écran. Nous voyons, le menu de l'éditeur de monde en haut, la fenêtre de vue 3D qui prend environ les deux tiers de l'écran, l'arbre d'édition dans le coin supérieur droit, et finalement, l'inspecteur en bas à droite 3.2.2.3.2 L'arbre d'édition Avant de sauter dans l'inspecteur relativement simple, discutons de l'arbre d'édition et des quelques fonctionnalités d'organisation fournies. Premièrement, déroulez la liste de l'arbre d'édition. La liste initiale est complètement repliée, ce qui ne permet pas de manipuler des objets. 1. Déroulez le MissionGroup – SimGroup en cliquant sur le [+] devant le texte ####: MissionGroup – SimGroup. Le nombre peut être différent de l'illustration 2. Déroulez le PlayerDropPoints – SimGroup. 3. Sélectionnez la SpawnSphere. 60 / 223 Documentation de Torque V1.3.x 3.2.2.3.3 SimGroups À ce point, vous pouvez vous demander, « Qu'est-ce que un SimGroup ? ». Les chapitres dans la section « École technique » entreront dans les détails sur SimGroups, SimSets, et SimObjects. Pour le moment, nous décrirons simplement les SimGroups en tant que moyen par lequel le moteur organise les objets. Ceci est à la fois utile pour une organisation sensée, c'est-à-dire en sachant trouver les choses pendant l'édition, et également utile pour les scripts. En prédéfinissant un jeu cohérent de SimGroups et en organisant vos objets avec eux, votre boulot en tant que concepteur de mission/niveau sera grandement simplifié. Vos concepteurs de scripts vous remercieront aussi. Si c'est votre boulot aussi, tapez-vous dans le dos. Bon travail ! Comme cela peut être vu dans la vue courante de l'arbre, un SimGroups peut contenir aussi bien un SimGroup qu'une entité particulière (SimObjects). En fait, chaque entité est présente dans cette liste et sera trouvée incluse dans un SimGroup. Ainsi, combien plaçons-nous exactement d'objets dans un SimGroup ? Découvrons-le. Premièrement, effectuez une copie de la SpawnSphere. Nous l'avons déjà sélectionnée, ainsi tout ce que vous avez à faire est de taper Ctrl+C (pour copier) suivi d'un Ctrl+V (pour coller). Alternativement, vous pouvez utiliser les options Copy/Paste du menu Edit. Maintenant que vous avez créé une nouvelle SpawnSphere, vous devez la localiser dans l'arbre d'édition. Hum ? Si vous avez suivi les instructions précédentes, vous trouverez la nouvelle SpawnSphere en bas de l'arbre. Hum, maintenant nous préférerons l'avoir dans PlayerDroppoints – SimGroup avec le reste des SpawSpheres. Bon, déplaçons manuellement celle-ci au bon endroit et apprenons comment classer des objets directement à la bonne place du premier coup. 3.2.2.3.3.1 Déplacement d'objets existants dans un SimGroup existant La nouvelle SpawnSphere devrait déjà être sélectionnée, mais si ce n'est pas le cas, veuillez cliquer dessus pour la sélectionner. Maintenant, utilisez l'ascenseur sur le côté droit de fenêtre de l'arbre et localisez le PlayerDropsPoints – SimGroup. Ensuite, cliquez sur la SpawSphere, puis glissez-la en maintenant le bouton de la souris enfoncé dans PlayerDropsPoints – SimGroup. 3.2.2.3.3.2 Fenêtre de l'inspecteur d'édition OK, maintenant intéressons-nous à l'inspecteur. C'est bien sûr, la fenêtre dont l'outil tire son nom. Le but de cette fenêtre est de vous permettre d'inspecter et de modifier les paramètres d'objets individuels. Si vous vous amusez un peu avec et cliquez sur différents objets, vous verrez que différents objets ont différents paramètres. Pour le moment, nous nous occuperons que des valeurs les plus communes, ajouterons de nouvelles valeurs, et finirons avec quelques astuces sur l'utilisation de l'interface. Nous aborderons en détail l'inspection des paramètres des objets dans le chapitre « L'école technique ». 3.2.2.3.3.3 Inspecteur – les champs communs Les champs communs sont : • Position (X, Y, Z) : trois valeurs en virgule flottante représentant les coordonnées de l'objet dans l'espace du monde. • Rotation (Xm, Ym, Zm, A) : quatre valeurs en virgule flottante où les trois premières sont les multiplicateurs et la quatrième valeur est l'angle (en degré) de la rotation. Exemple : rotation 0 1 0 90.0 signifie que l'objet est tourné de 90 degrés autour de l'axe y, relativement aux axes du monde. • Scale (Xm, Ym, Zm) : trois valeurs en virgule flottante représentant une échelle échelle relative. Les valeurs fonctionnent comme des multiplicateurs des dimensions par défaut de l'objet dans les 61 / 223 Documentation de Torque V1.3.x axes indiqués. • • Exemple : scale 1 1 2 signifie que cet objet sera deux fois plus haut que sa hauteur par défaut lors de son chargement dans le monde. Note : ces valeurs correspondent indirectement à celles vues lors du dimensionnement à la souris. Les valeurs de dimensionnement à la souris sont actuellement les dimensions du monde. • ShapeName (seulement pour les formes) : ce nom de paramètre est impropre. Actuellement, il donne le chemin relatif et le nom du fichier de la forme sélectionnée. • InteriorFile (seulement pour les intérieurs) : ce paramètre donne le chemin relatif et le nom du fichier de l'intérieur sélectionné. • Name : Le champ texte est situé à droite du bouton Apply. Vous pouvez taper n'importe quel nom (sans espace) et cliquez Apply pour nommer votre objet. Note : des objets peuvent avoir des noms identiques. Nous parlerons davantage du nom des objets dans un chapitre ultérieur. Souvenez-vous juste comment modifier le nom à partir de l'inspecteur. 3.2.2.3.3.4 Inspecteur – les champs dynamiques Je n'expliquerai pas encore ce que sont les champs dynamiques, mais plutôt un moyen pour en ajouter. Je dirai cependant que les champs dynamiques sont une fonctionnalité importante pour les scripts et que vous aimerez les utiliser. • Pour ajouter un champ dynamique : • • • • Pour modifier la valeur d'un champ dynamique : • • Sélectionnez l'objet auquel vous souhaitez ajouter un champ Cliquez sur le bouton vertical Add Field à gauche de la section Dynamics Fields de la fenêtre d'inspection. Dans le champ ajouté, donnez un nom à votre nouveau champ, et une valeur à celui-ci. Comme pour la modification de la valeur des autres champs, modifiez juste le contenu du champ texte à côté du nom du champ dynamique et cliquez sur Apply. Pour supprimer un champ dynamique : • Cliquez sur la petite poubelle à gauche du nom du champ dynamique. Attention, cette suppression n'est pas annulable (undo). 3.2.2.4 Éditeur de monde (Creator) Lancement du créateur (Creator) 1. Lancez l'éditeur de mission en appuyant sur F11 2. Lancez le créateur en appuyant F4 3.2.2.4.1 La fenêtre du créateur Cet outil est utilisé pour créer (ou placer) de nouveaux contenus. À partir du créateur, nous pouvons sélectionner des objets à insérer dans notre mission courante. Les répertoires les plus hauts sont : • Interiors (intérieurs) – bâtiments et autres intérieurs. • Shapes (formes) – formes pouvant être animées. 62 / 223 Documentation de Torque V1.3.x • Static Shapes (formes statiques) – formes légères inanimées. • Mission Objects • • • Éléments environnementaux tels le ciel, le soleil ou l'eau. Éléments de mission tels la MissionArea (zone de mission), les Triggers (déclencheurs), et les Cameras (caméras) Éléments système tels les SimGroups 3.2.2.4.2 Placement (création) de nouveaux objets La création de nouveaux objets est très similaire au collage d'objets. Simplement, 1. Déplacez-vous dans la zone de la mission où vous souhaitez placer l'objet 2. Regardez approximativement l'endroit où vous souhaitez placer l'objet (il n'y a malheureusement pas de prépositionnement possible, il n'y a pas de réticule pour marquer l'endroit). 3. Trouvez l'objet que vous souhaitez placer en regardant dans l'arbre du créateur. 4. Cliquez une fois sur l'objet dans la liste. Une fois qu'un objet est placé dans le monde, vous pouvez manipuler librement sa position, sa rotation, et son échelle via la souris. Si cependant, vous voulez changer des paramètres de l'objet, vous devrez aller dans l'inspecteur. 3.2.2.4.3 Astuces du créateur Il y aura une FAQ dans les annexes qui traitera des problèmes communs, mais je vais lister quelques questions ici, car elles sont tellement communes, et que ceci est la bonne place pour en discuter. Q : « J'ai placé un interior et les textures ne sont pas visibles. Pourquoi ? » R : Différents des Shapes, les interiors n'affichent pas immédiatement leurs textures lorsqu'ils sont insérés dans le monde. Ils doivent être traités par une étape d'éclairage (souvenez-vous du message Lighting Mission – éclairage de la mission – lors du démarrage de la mission). Une fois que vous avez placé un interior, appuyez sur Alt+L pour lancer le calcul des éclairages de la scène. Ceci peut prendre quelques secondes, ceci dépend de la complexité, de la taille, et de la densité de la mission. Q : « Comment puis-je place avec précision mes objets la première fois ? » R : Le placement initial d'un objet est déterminé par une ligne de visée. Il y a trois cas de placement de base. Dans les deux premiers cas, un rayon est lancé à partir de l'œil de la caméra/joueur jusqu'à ce qu'il rencontre la boîte de sélection d'un autre objet de la mission ou le terrain/eau. Dans l'un ou l'autre de ces cas, l'objet est placer au point de collision. Le troisième cas est lorsque l'œil de la caméra/joueur vise au-dessus de l'horizon. Dans ce cas, le lancé de rayon échoue (pas de collision) et l'objet est placé au départ du rayon (c'est-à-dire d'où vous regardez). Concernant les collisions avec les boîtes de sélection, je ne compterais pas que cela fonctionne toujours. J'ai eu beaucoup de cas où le rayon rencontrait le sol à la place de la cible prévue. Habituez-vous juste à l'idée que vous aurez à peaufiner la position des choses après leur placement. 3.2.2.4.4 Ajout d'objets dans l'arbre du créateur Si vous avez parcouru le répertoire example/fps, vous pouvez avoir noté une similarité entre la structure des répertoires et la hiérarchie du créateur. Ceci est dû au fait qu'il y a une dépendance (la plupart du temps pour les interiors). Une discussion plus complète sera donnée dans « L'école technique ». Table 17 : le créateur vs l'arborescence. 63 / 223 Documentation de Torque V1.3.x Bien qu'une discussion complète sur l'ajout de nouveaux intérieurs ou de nouvelles formes soit en dehors du périmètre de cette section, je décrirai les étapes les plus fondamentales nécessaires pour entrer de nouveaux interiors et shapes dans l'arbre du créateur. 3.2.2.4.5 Ajout d'interiors dans l'arbre du créateur Torque nécessite les fichiers suivants pour créer un interior : • DIF – Une fois qu'un interior a été proprement généré, il y aura un fichier nommé nom_interior.dif, où nom_interior est ce que vous aurez choisi comme nom pour votre objet interior. • Fichier(s) graphique(s) – un interior non transparent aura au moins un fichier graphique. Par défaut, les fichiers graphiques utilisés pour les intérieurs nécessitent d'être situés dans un répertoire au-dessus du fichier DIF de l'interior ou dans le même répertoire que le fichier DIF. Exemple : 1. Dans le répertoire : example\egt\data\interiors\abcschack vous trouverez un fichier nommé abcshack.dif. Faites une copie de ce fichier et renommez-le : myabcshck.dif. 2. Sortez complètement du SDK, redémarrez-le, et relancez l'éditeur de mission. 3. Maintenant, dans l'arbre du créateur, sous Interiors -> egt -> data -> Interiors -> abcshack, vous verrez un nouvel interior nommé : myabcshack. Essayez de la placer. 3.2.2.4.6 Ajout de Shapes dans l'arbre du créateur Torque nécessite les fichiers suivants pour créer une Shape : • DTS – Une fois qu'une shape a été proprement générée, il y aura un fichier nommé nom_shape.dts, où nom_shape est ce que vous aurez choisi comme nom pour votre objet shape. • Fichier(s) graphique(s) – une shape non transparente aura au moins un fichier graphique. Par défaut, les fichiers graphiques utilisés pour les intérieurs nécessitent d'être situés dans le même répertoire que le fichier DTS. • DSQ(s) (optionnel) – pour une shape animée créée dans 3D Max (ne s'applique pas pour les shapes créées avec Milkshape), il y a un troisième type de fichier, contenant les données d'animation. Dans un souci de simplicité, ceci ne sera pas traité ici, sinon pour noter qu'il peut exister. Par défaut, les fichiers DSQ utilisés pour les shapes nécessitent d'être placées dans le 64 / 223 Documentation de Torque V1.3.x même répertoire que le fichier DTS. Exemple : 1. Dans le répertoire : example\egt\data\shapes\Simple vous trouverez un fichier nommé cube.dts. Faites une copie de ce fichier et renommez-le : mycube.dts. 2. Sortez complètement du SDK, redémarrez-le, et relancez l'éditeur de mission. 3. Maintenant, dans l'arbre du créateur, sous Static Shapes -> egt -> data -> Shapes -> Simple, vous verrez une nouvelle shape nommée : mycube. Essayez de la placer. Vous pourriez vous demander pourquoi l'objet est apparu dans Static Shapes au lieu de Shapes. Les objets sous Static Shapes sont les objets « légers ». En plus, vous pouvez faire quelques scripts pour créer des objets avec des animations et autres caractéristiques. Ils apparaîtront sous Shapes. Vous en apprendrez plus sur le sujet dans le chapitre « Formation au boulot ». Pour le moment, allons dans l'éditeur de zone de mission. 3.2.2.5 Éditeur de zone (Area Editor) Lancement de l'éditeur de zone 1. Lancez l'éditeur de mission en appuyant sur F11 2. Lancez l'éditeur de zone en appuyant F5 3.2.2.5.1 La fenêtre de l'éditeur de zone Dans le coin droit de l'écran, vous verrez une image en bleu et blanc. Cette image représente la carte de la mission. L'éditeur de zone fournit la possibilité de sélectionner la taille et la position des limites de la mission (ou zone). Étrangement, il fournit aussi une possibilité d'édition du terrain. Il convient de noter que la manipulation des zones de mission semble avoir des effets secondaires. En particulier, lorsque vous recentrez la zone de mission, il tend à déplacer les interiors et les shapes dans la mission. Le problème est que ce mouvement semble être incohérent. Ainsi, mon conseil est, si vous allez ajuster votre zone de mission, faites-le avant de placer un nombre significatif d'objets dans votre mission, ou vous pourriez être très dérangé par le résultat. Maintenant, jetons un coup d'œil sur les parties de l'éditeur et expliquons son fonctionnement. 3.2.2.5.2 Édition la zone de mission L'éditeur de zone de mission est très simple à utiliser. Cliquez simplement la case à cocher Edit Area et des poignées apparaîtront sur la boîte de la zone de mission. Maintenant, glissez et dimensionnez suivant votre envie. Vous serez capable de voir les effets de vos modifications dans la vue 3D. Une chose à conserver à l'esprit est que l'image est inversée. C'est-à-dire que le haut de l'image est considéré comme le sud, le bas le nord, et la gauche et la droite respectivement l'ouest et l'est. Ceci devrait rapidement devenir difficile à se rappeler, ainsi, les concepteurs de l'éditeur de zone fournissent un dispositif pour vous donner une meilleure vue de ce que vous regardez lorsque vous éditez. Le dispositif dont je parle est le champ de vision Field Of View – FOV (champ de vision). Regardez l'exemple suivant : [L'image annoncée est absente du document original] Avant de poursuivre, il y a deux choses que vous devez savoir : 1. Vous pouvez utiliser la fenêtre d'édition de zone pour rapidement repositionner votre 65 / 223 Documentation de Torque V1.3.x personnage/caméra. Simplement, soyez sûr que la case à cocher Edit Area n'est PAS cochée et cliquez dans la fenêtre. Votre personnage/caméra (dépendant de votre mode de vue) « sautera » à ce point. 2. L'éditeur de zone a (ce que je considère) un petit bogue. Si vous avez effectué des modifications sur votre terrain en utilisant le terraformeur ou l'éditeur de terrain, ces modifications ne seront pas automatiquement reflétées dans l'image de l'éditeur de zone. Pour rafraîchir l'image, faites ceci : 1. 2. 3. 4. Effectuez les modifications de votre terrain Lancez l'éditeur de zone et assurez-vous que Edit Area est coché Glissez la zone de la mission décentrée Recentrez en cliquant sur le bouton Center. Le terrain mis à jour devrait refléter l'image de l'éditeur de mission La morale de cette histoire est : « Éditez en premier la topologie de votre terrain, puis éditez votre zone de mission. Et...! faites tout ceci avant le placement des interiors et des shapes ». 3.2.2.5.3 Inverser la zone de mission Comme mentionné précédemment, l'éditeur de zone permet ce que j'ai appelé une fonctionnalité d'édition de terrain. À savoir, la possibilité d'inverser le terrain. Ceci est très utile si vous souhaitez créer une zone équilibrée de mission (en terme d'accidents de terrain). Pour utiliser cette fonctionnalité, cliquez sur le bouton Mirror et vous devrez voir l'image suivante : Application du miroir Annulation du miroir Rotation du plan miroir Destination du miroir Plan du miroir Source du miroir Le principe de cet outil est simple : • • Sélectionnez l'orientation du plan d'inversion (avec les boutons fléchés gauche et droite). Cliquez Apply pour copier l'inversion de la source sur la destination. 3.2.2.6 Éditeur de terrain (Terrain Editor) Lancement de l'éditeur de terrain : 1. Lancez l'éditeur de mission en appuyant sur F11 2. Lancez l'éditeur de terrain en appuyant F6 3.2.2.6.1 La fenêtre de l'éditeur de terrain Lorsque vous lancez l'éditeur de terrain, vous verrez quelque chose comme la copie d'écran ci-dessus. Cela ressemble beaucoup à la vue du manipulateur, du fait qu'il n'y a pas de fenêtres réduisant votre vue. Cependant, si vous regardez bien, vous noterez quelques carrés autour de votre curseur suivant les mouvements de votre souris. Ces carrés sont encore un autre dispositif de l'interface utilisateur de Torque, 66 / 223 Documentation de Torque V1.3.x son but est de vous donner un retour sur quelle zone de terrain sera affectée lorsque vous choisirez de la manipuler et jusqu'à quel point elle sera affectée. Avant de continuer dans l'édition de terrain, regardons les deux autres éléments de l'écran 3.2.2.6.2 L'échelle de la brosse de vertex Je suis sûr que certains corrigeront ce nom, mais pour le moment, je référencerai le texte du label Mouse Brush ainsi « Échelle de la brosse de vertex ». Le but de cette échelle est double : 1. Elle indique combien de vertices sont actuellement sous la brosse. Dans l'image ci-dessus, nous avons 69 blocs sous la brosse. 2. Elle indique l'élévation moyenne des vertices sous la brosse. 3.2.2.6.3 L'échelle de sélection de la brosse normale À nouveau, je suis sûr que certains me diront que mon choix de nom est incorrect, mais pour le moment, je référencerai le texte du label Selection ainsi : « Échelle de sélection de la brosse normale ». Le but de cette échelle est double : 1. Elle indique combien de vertices sont actuellement sélectionnés (nous appréhenderons la sélection plus loin). 2. Elle indique l'élévation moyenne des vertices sélectionnés. 3.2.2.6.4 Édition Il y a deux modes de base pour l'édition via l'éditeur de terrain : 1. Mode brosse – le mode par défaut est une brosse libre de 9x9 vertices. Vous pouvez ajuster la forme et la dureté de la brosse aussi bien que sa taille. En plus, ce mode permet plusieurs opérations. 2. Mode sélection – le second mode, que j'utilise moins fréquemment, mais qui peut faire des choses que vous ne pouvez pas faire en mode brosse. Dans ce mode, vous sélectionnez arbitrairement des blocs de terrain. Ensuite, vous pouvez effectuer une seule opération dessus, qui est de modifier leur hauteur via la souris. 3.2.2.6.5 Édition en mode brosse Je pense qu'il est juste de dire que la plupart de vos éditions seront faites en mode brosse, et puisque c'est le mode par défaut, je commencerai par lui. Comme indiqué précédemment, vous pouvez modifier la forme, la dureté et la taille de la brosse. L'illustration ci-dessous en décrit les détails, qui sont modifiables dans le menu Brush. OK, maintenant que nous connaissons les bases de la manipulation des brosses, qu'en est-il des opérations ? Jetons un œil au menu action. 67 / 223 Documentation de Torque V1.3.x Forme de brosse : il y a deux formes de base. ● Une boîte ● Un cercle Vous pouvez sélectionner Box ou Circle. Dureté de brosse : la dureté est une manière imagée de décrire la puissance de l'effet de la brosse. Ceci sera décrit en profondeur plus loin, mais pour le moment, considérons une brosse dure comme ayant une action de 100 %, tandis qu'une brosse douce peut être variable au travers de son diamètre. Vous pouvez choisir Soft ou Hard. Taille : vous pouvez sélectionner une des tailles de brosse. Prenez note des raccourcis clavier. Table 18 Action Description Add Dirt (ajout de terre) Élève le terrain sous la brosse Excavate (creuser) Abaisse le terrain sous la brosse Adjust Height hauteur) (ajuster la Sélectionne temporairement les vertices sous la brosse. Le niveau du terrain suit les mouvements de la souris. Flatten (aplatir) Place tous les vertices sous la brosse à une hauteur moyenne. Smooth (lisser) Réalise une hauteur moyenne pour les vertices voisins sous la brosse. Set Height (régler la hauteur) Place tous les vertices à une hauteur prédéfinie (voir les paramètres de l'éditeur de terrain pour positionner ce paramètre). Set Empty (vider) Ceci supprime le terrain entre les bords extérieurs de la brosse. Clear Empty (annuler le vide) Annule la suppression du terrain. Paint Material matériel) (peindre le Peint les vertices avec la texture sélectionnée courante (voir le chapitre : Peinture de texture de terrain). 3.2.2.6.6 Sélection en mode brosse Bien, que diriez-vous de cette autre mode, Selection ? Il n'a pas vraiment beaucoup pour lui. Pour passer en mode sélection, ouvrez simplement le menu Action et cliquez sur Select. Maintenant, vous pouvez sélectionner le terrain ainsi : Table 19 Action Description Sélectionne un vertex (peut augmenter la puissance de l'action – voir la discussion sur la dureté de la brosse – si le curseur de sélection a une valeur plus forte que la force d'action du vertex actuellement sélectionné) Ctrl+ Désélectionne les vertices Après avoir sélectionné les blocs de terrain que nous souhaitons modifier, nous pouvons ouvrir le menu Action et cliquez Adjust Selection. Maintenant, nous pouvons cliquer pour élever ou baisser le niveau des blocs sélectionnés. Pour quitter le mode sélection, sélectionnez n'importe quelle autre opération dans le menu Action. De même, une fois sélectionnés, les vertices restent sélectionnés, en fonction du mode,. Si vous souhaitez désélectionner tous les vertices sélectionnés, appuyez sur Ctrl+N ou cliquez Select None dans le menu Edit. 68 / 223 Documentation de Torque V1.3.x 3.2.2.6.7 Dureté de brosse La dureté de la brosse a été mentionnée plusieurs fois, mais n'a pas été entièrement expliquée. Lorsque la dureté de la brosse est sur Soft (douce), la force de l'action suivant le diamètre de la brosse peut être modifiée. En termes simples, si la force de l'action est réglée sur faible, alors le changement de valeur pour cette partie de la brosse est également faible. Vice versa, si la force de l'action est réglée sur forte, le changement de valeur pour cette partie de la brosse sera élevé. Cette atténuation est en relation avec le mouvement de la souris. La brosse donne l'information de la force de l'action au travers de la coloration. La coloration de la brosse est une échelle continue du rouge vers le vert. Vous pouvez manipuler cette dureté dans la boîte de dialogue des paramètres de l'éditeur de mission (Terrain Editor Settings) situé dans le menu Edit. Table 20 Couleur Dureté relative (Force de l'action) Rouge Très dure (100%) Orange Dure (plus de 50%) Jaune Douce (moins de 50%) Vert Très douce (presque 0%) Par exemple, la brosse ci-dessous est dure dans le milieu s'adoucissant progressivement sur les bords. 3.2.2.6.8 Paramètres de l'éditeur de terrain Précédemment, j'ai différé une discussion sur ces paramètres. Maintenant, il est temps de les comprendre. En plus d'être capable d'ajuster la forme, la dureté et la taille de la brosse, la boîte de dialogue Terrain Editor Settings, située sous le menu Edit, nous donne quelques contrôles supplémentaires. 3.2.2.6.9 Paramètres de l'éditeur de terrain 69 / 223 Documentation de Torque V1.3.x Cette échelle spline modifie la dureté de la brosse. À gauche, c'est le centre; à droite, c'est l'extrême bord. Ajustement de l'incrément de hauteur Élévation pour l'opération d'affectation de hauteur Ajustement de l'incrément de l'échelle de hauteur Facteur de lissage – les valeurs faibles sont moins agressives. <Radius> semble impliquer qu'il y a une manière d'affecter le rayon de la brosse. Malheureusement, cela ne s'applique en mode sélection (voir plus loin) Cliquez sur Apply pour que les modifications prennent effet. Ok ne fait rien, c'est le bouton Cancel (Annuler) 3.2.2.6.10 Sélection et rayon J'ai eu un peu de difficulté à comprendre <Radius> (rayon) lors de mon apprentissage du moteur. Ainsi, au lieu de tenter de l'expliquer avec des mots, je vous donnerai un exemple graphique qui devrait éclaircir cela. Dans la séquence suivante, je suis passé en mode sélection et j'ai utilisé une brosse de 1x1. J'ai alors sélectionné un vertex unique et ouvert la boîte de dialogue Terrain Editor Settings. Rayon = 1 Rayon = 8 Rayon = 12 Rayon = 16 3.2.2.7 Éditeur de terraformation (Terrain Terraform Editor) Lancement de l'éditeur de terraformation : 1. Lancez l'éditeur de mission en appuyant sur F11 2. Lancez l'éditeur de terraformation en appuyant F7 3.2.2.7.1 Aperçu du terraformeur Comme tous les outils intégrés à l'éditeur, le terraformeur est probablement l'un des plus élaborés et compliqués. L'une des plus courtes définitions données à cet outil est un outil algorithmique pour construire des terrains. Vous pouvez demander, « Pourquoi voudrais-je utiliser cet outil pour construire mes terrains ? » La raison numéro un à laquelle on peut penser est : c'est une méthode rapide pour créer des terrains 70 / 223 Documentation de Torque V1.3.x intéressants. Je dois admettre, j'ai lutté avec cette partie du guide. Je voulais fournir une couverture complète de tous les domaines de discussion, mais au même moment, je voulais terminer le guide en un temps raisonnable. Considérant le fait que vous ne tireriez aucun avantage de ce guide si je ne le finissais pas rapidement, j'ai décidé de décrire cet outil de manière générale. Cela dit, je donnerai les détails suivants sur le terraformeur : 1. 2. 3. 4. 5. description de la fenêtre de terraformation résumé de toutes les opérations découverte du mode d'application des opérations brèves descriptions des interfaces des opérations individuelles une liste des factoids du terraformeur 3.2.2.7.2 Fenêtre de prévisualisation de terraformation Si vous parcourez ce guide depuis le début, ce sera la première fois que nous voyons cette fenêtre particulière. Vous noterez qu'elle est similaire à la fenêtre de l'éditeur de zone (Mission Area Editor). En fait, cette fenêtre affiche des données très similaires. Lors de cette discussion, nous focaliserons sur les aspects suivants : 1. marqueur central – il y a une petite croix blanche dans la fenêtre de prévisualisation. Elle marque le centre de la carte. À chaque fois que vous appliquez une opération de terraformation, c'est l'endroit où sera déplacée la caméra. 2. marqueur FOV (Field Of View) – il y a un V rouge qui est toujours au centre de la fenêtre. Cela montre votre vue courante. Par exemple, la zone relative vue sur la carte. 3. Marques de limites – en plus du marqueur central, il y a des lignes horizontales et verticales, représentant les frontières de la carte d'élévation. 4. Image de la carte d'élévation – bien qu'il puisse ne pas être évident au début, l'image dans la fenêtre de prévisualisation est une traduction de la carte d'élévation. La coloration funky peut être interprétée très facilement. Plus une zone est sombre, plus basse elle est. De même, plus une zone est claire, plus elle est élevée. 3.2.2.7.3 Arbre des opérations de terraformation Dans le coin inférieur droit de l'écran, vous trouverez l'arbre des opérations de terraformation. Ceci est un bouton libellé Operations. En cliquant dessus, il apparaîtra un menu déroulant avec toutes les opérations. Lorsque vous sélectionnez une opération, elle est ajoutée après l'opération surlignée courante (ainsi, vous pouvez insérer de nouvelles opérations dans le milieu d'une liste d'opérations existantes). 71 / 223 Documentation de Torque V1.3.x Arbre des opérations de terraformation Menu déroulant des opérations de terraformation 3.2.2.7.4 Opérations de terraformation Chacune des opérations de terraformation a ses propres paramètres. Ceux-ci peuvent être accédé dans la fenêtre supérieure haute. Avant de les parcourir, énumérons et décrivons rapidement les propriétés générales des opérations. Dans son guide d'édition de Tribes, Editing Maps and Missions in Tribes 2, Tim Hammock classe convenablement les opérations en tant que : générateurs ou filtres. En plus, j'aimerais ajouter la catégorie : base. Le tableau suivant donne un résumé des opérations : Base, Générateur et Filtre. Table 21 : opérations Base Base General Résumé Ceci est l'opération par défaut. Elle ne peut pas être retirée de votre liste des opérations. Les valeurs initialisées dans cette opération sont utilisées par les générateurs et filtres suivants. Table 22 : opérations Générateur Base Résumé fBm Fractal Le générateur aléatoire fractal (fBm = fractional Brownian motion) est un générateur de terrain de base. Il produit des collines avec diverses inclinaisons basées sur les paramètres. Il tend à produire des collines lissées, mais peut produire des crêtes irrégulières. Rigid MultiFractal Un autre générateur basé sur les fractales, tendant à produire des collines avec des crêtes dentelées (ou pointues) Canyon Fractal Ce générateur basé sur les fractales produit une série de cuvettes (gorges). Il peut produire des gorges peu ou très profondes, droites ou courbes. Sinus Ce générateur est pratiquement impossible à manipuler sans code. Cependant, un coup d'œil rapide montre que ce générateur crée des terrains en ajoutant itérativement la somme mise à l'échelle d'une paire de sinus et cosinus avec quelques bruits de base pour le visuel. Oubliez ce générateur. La description n'est pas entièrement correcte et même si elle l'était, cela ne signifierait pas grandchose. Souvenez-vous juste de ceci, en ignorant l'élément bruit, tous les terrains produits avec ce générateur ont la même forme de base. Votre choix de paramétrage déterminera comment cette forme est appliquée progressivement sur des sections plus petites du terrain. Je donnerai plus de détails plus loin. Terrain File Cette opération devrait vous permettre d'importer un fichier de terrain précédemment créé, mais pour le moment, elle ne fonctionne pas. 72 / 223 Documentation de Torque V1.3.x Base Résumé Bitmap Cette opération vous permet d'importer un fichier d'image comme carte d'élévation du terrain. Table 23 : opérations Filtre Base Résumé Turbulence Ce filtre érode et redistribue algorithmiquement une brosse. les éléments du terrain, et applique Smoothing Ceci est un simple filtre faisant la moyenne des points voisins. Il tendra à supprimer les zones irrégulières du terrain. Smooth Water Ceci est comme le filtre précédent, mais il limite le lissage du terrain au-dessous ou au niveau de la hauteur globale de l'eau (paramétré dans l'opération General). Aucun lissage n'est effectué pour les éléments au-dessus du niveau de l'eau. Smooth Ridges/Valleys Comme le nom l'indique, ce filtre affecte des régions spécifiques basées sur leurs caractéristiques. Les plateaux avec des bords déchiquetés seront arrondis sur les bords tout en conservant leurs inclinaisons originales. Les rides profondes dans les vallées seront comblées, en fonction du paramétrage. Filter Ce filtre vous permet d'ajuster globalement des groupes de même élévation. En d'autres termes, les hauteurs de terrain sont divisées en groupes distincts modifiables, de l'élévation la plus basse à la plus élevée. Thermal Erosion Ceci est un filtre d'érosion très agressive. Avec lui, vous pouvez rapidement enlever de la matière sur les zones inclinées de votre terrain. La documentation officielle indique que le filtre utilise un algorithme d'érosion thermique. Hydraulic Erosion Ceci est un filtre d'érosion très faible. La documentation officielle indique que le filtre utilise un algorithme d'érosion hydraulique. Blend Ce filtre vous permet de combiner deux opérations existantes via un jeu d'opérations mathématiques. Nous jouerons avec lui plus tard. 3.2.2.7.5 Comment les opérations sont appliquées Les opérations sont appliquées sur le terrain dans l'ordre où elles apparaissent dans la liste, du haut vers le bas. Cela signifie que si vous appliquez deux générateurs dans une ligne, seul le résultat du second générateur sera vu. Plus intéressant, vous pouvez appliquer les filtres dans différents ordres pour différents résultats. Le meilleur moyen d'apprendre ces opérations est l'expérimentation. Cela dit, je donnerai un coup d'œil rapide sur les différents paramètres des opérations. 3.2.2.7.6 Paramétrage des opérations 3.2.2.7.6.1 General Table 24 : General 73 / 223 Documentation de Torque V1.3.x • • • • Min Terrain Height (0..500) – définit le point le plus bas de la carte. Les outils et générateurs ne peuvent pas créer une élévation de terrain en dessous de ce point. Height Range (5..500) – définit l'amplitude maximale entre la hauteur minimale et maximale. Par conséquent, Élévation max. = hauteur min. + amplitude max. Water Level – est une valeur globale utilisée comme entrée des filtres suivants. Il ne place pas d'eau. Center on Camera – place l'origine de la carte à la position courante de la caméra. 3.2.2.7.6.2 Fbm Fractal Table 25 : fBm Fractal • • • • • Hill Frequency (1..24) – détermine indirectement le nombre de collines. Une valeur plus élevée crée plus de collines. Roughness (0.0..1.0) – définit l'arrondi des collines. Les valeurs les plus faibles tendent à créer plus de collines arrondies, tandis que des valeurs plus élevées créent des collines plus grandes et plus pointues. Par exemple, avec des pentes plus raides. Detail (Very Low..Very High) – en terme de résultats visuels, des valeurs élevées produisent des crêtes plus déchiquetées (arêtes en lame de couteau). Random Seed – valeur initiale du générateur aléatoire. L'utilisation de la même valeur pour les générations suivantes produit les mêmes séquences de nombres. New Seed – crée une nouvelle valeur initiale pour le générateur aléatoire. Astuces : • • si, l'amplitude de hauteur est grande (disons supérieure à 350), vous tendez à avoir des collines déchiquetées, sans se soucier des autres paramètres. avec une amplitude par défaut élevée (300), Very High Detail tendra à créer des collines en lame de couteau, même avec une faible valeur pour Hill Frequencies (8). 3.2.2.7.6.3 Rigid MultiFractal Table 26 : Rigid MultiFractal 74 / 223 Documentation de Torque V1.3.x • • • • • Hill Frequency (1..24) – détermine indirectement le nombre de collines. Une valeur plus élevée crée plus de collines. Roughness (0.0..1.0) – définit l'arrondi des collines. Les valeurs les plus faibles tendent à créer plus de collines arrondies, tandis que des valeurs plus élevées créent des collines plus grandes et plus pointues. Par exemple, avec des pentes plus raides. Detail (Very Low..Very High) – en terme de résultats visuels, des valeurs élevées produisent des crêtes plus déchiquetées (arêtes en lame de couteau). Random Seed – valeur initiale du générateur aléatoire. L'utilisation de la même valeur pour les générations suivantes produit les mêmes séquences de nombres. New Seed – crée une nouvelle valeur initiale pour le générateur aléatoire. 3.2.2.7.6.4 Canyon Fractal Table 27 : Canyon Fractal • • • • Canyon Frequency (4..10) – nombres de vallées à produire. Chaos (0.0..1.0) – une valeur à zéro produira des vallées droites et à l'apparence artificielle. Une valeur de 1 produira des vallées pratiquement méconnaissables. Random Seed – valeur initiale du générateur aléatoire. L'utilisation de la même valeur pour les générations suivantes produit les mêmes séquences de nombres. New Seed – crée une nouvelle valeur initiale pour le générateur aléatoire. 3.2.1.1.1.1 Sinus Table 28 : Sinus • • • • Scale (on..off) – ici, l'échelle ne fournit pas tout à fait l'effet escompté. Bien qu'elle implique qu'il y ait une gamme de valeurs pour chaque point de contrôle, les valeurs sont soit on ou off. Glisser un point de contrôle vers le bas, la met à off. N'importe quelle autre position verticale est on. Random Seed – valeur initiale du générateur aléatoire. L'utilisation de la même valeur pour les générations suivantes produit les mêmes séquences de nombres. New Seed – crée une nouvelle valeur initiale pour le générateur aléatoire. Control Points – nombre de points de contrôles sur l'échelle. Plus de points de contrôle signifient plus de détails. Par exemple, un niveau plus élevé de subdivisions et d'itérations. Comme mentionné avant, ce générateur construit le terrain en utilisant une combinaison de valeurs sinusoïdales et de bruits. Si vous souhaitez voir la structure fondamentale, initialisez à zéro le générateur aléatoire (seed). Maintenant, « tripatouiller » les points de contrôle produira quelque chose comme ça : Maintenant, réglez sur 3 le nombre de points de contrôle. Notez que la structure globale est encore 75 / 223 Documentation de Torque V1.3.x reconnaissable : 3.2.1.1.1.1 Turbulence Table 29 : Turbulence 76 / 223 Documentation de Torque V1.3.x • • Turbulence Factor (0..1.0) – détermine la puissance de l'action. Une valeur faible signifie moins de déplacement et moins de variation en hauteur. Une valeur élevée signifie des modifications et des tourbillons vigoureux sur la hauteur. Radius of Effect (1..40) – détermine la taille du filtre. Je crois que 1 égal à un filtre 3x3, 2 égal à un filtre 4x4, etc., jusqu'à un filtre 32x32. 3.2.1.1.1.2 Smoothing Table 30 : Smoothing • • Iterations (0..40) – détermine le nombre de passe de lissage à effectuer. Aggressiveness (0.0..1.0) – un facteur relatif déterminant la quantité de matériau à retirer. 3.2.1.1.1.3 Smooth Water Table 31 : Smooth Water • • Iterations (0..40) – détermine le nombre de passe de lissage à effectuer. Aggressiveness (0.0..1.0) – un facteur relatif déterminant la quantité de matériau à retirer. 3.2.1.1.1.4 Smooth Ridges/Valleys Table 32 : Smooth Ridges/Valleys 77 / 223 Documentation de Torque V1.3.x • • Iterations (0..40) – détermine le nombre de passe de lissage à effectuer. Aggressiveness (0.0..1.0) – un facteur relatif déterminant la quantité de matériau à retirer. 3.2.1.1.1.5 Filter Table 33 : Filter • • Scale – chaque point de contrôle correspond à une hauteur spécifique (voir après pour le calcul). Les applications suivantes changent ces valeurs. Control Points – détermine maintenant le nombre de bandes d'élévation. Vous pouvez effectuer de significatives et rapides modifications sur votre terrain avec ce filtre. Comprendre son fonctionnement peut être rusé. Premièrement, vous pouvez penser que la portée de l'action sera basée sur la hauteur minimale (Min Terrain Height) et l'amplitude de la hauteur (Height Range) indiquées dans les paramètres de General. Ceci peut être ou ne pas être vrai. Si votre terrain courant va du point le plus bas au plus élevé, alors, oui. Cependant, disons que votre hauteur minimale (Min Terrain Height) est à 0, mais que votre plus basse élévation est 100. En outre, l'amplitude de la hauteur (Height Range) est à 200, mais votre plus haute élévation est de seulement 200 (la moitié de l'amplitude). Alors, les bandes d'élévation sont déterminées ainsi : • • • • • Élévation la plus basse : 100 mètres Élévation la plus haute : 200 mètres Points de contrôles : 5 Largeur de chaque bande d'élévation : (200-100)/5 = 20 mètres Bandes d'élévation résultantes (de gauche à droite) : Point de contrôle 1 Point de contrôle 2 Point de contrôle 3 Point de contrôle 4 Point de contrôle 5 100..119 mètres 120..139 mètres 140..159 mètres 160..179 mètres 180..200 mètres Déplacer un point de contrôle, c'est comme glisser toutes les élévations dans cette bande et de les élever ou les abaisser d'une quantité relative. En plus, je crois qu'il y a une relation de vases communicants entre les bandes d'élévation. Ainsi, en modifiant une bande, vous modifiez (légèrement) toutes les élévations des autres bandes. Ci-après, voue verrez quelques exemples de modification ainsi vous jugerez par vous même. Quelque soit le cas, cet outil modifie rapidement l'apparence de votre terrain, ainsi prudence est le mot. 78 / 223 Documentation de Torque V1.3.x Note : par défaut, l'échelle ressemble à ceci (sauf qu'elle a sept points de contrôle). Si elle reste ainsi, aucune modification ne sera effectuée. Ici, nous augmentons la bande d'élévation basse autant que possible, en nous souvenant que les valeurs les plus lumineuses sont les élévations les plus élevées, notez que certains motifs précédemment sombres sont maintenant lumineux. En outre, notez que l'élévation totale de la carte semble avoir baissé. Intéressant. Ici, nous baissons la bande d'élévation la plus haute autant que possible. C'est alors que les zones précédemment hautes sont maintenant complètement sombres, mais que s'est-il passé d'autre ? Le niveau zéro de la carte semble avoir été remonté. Bien curieux. Dans cet exemple, nous avons descendu toutes les bandes sauf celle du milieu. Comme cela peut être vu aisément, nous avons donné à la bande centrale la plus grande amplitude. 3.2.1.1.1.6 Thermal Erosion Table 34 : Thermal Erosion 79 / 223 Documentation de Torque V1.3.x • • • Iterations (0..40) – détermine le nombre de passe de lissage à effectuer. Min Erosion Slope (0.0..89.0 en degrés) – définit une valeur limite de pente. Cela indique de ne pas appliquer cette érosion avec une valeur inférieure à celle indiquée. C'est-à-dire que si une pente a une inclinaison de 15 degrés et que la valeur est à 45, aucune modification ne sera effectuée sur cette partie de la carte. Material Loss (0..100) – pourcentage relatif de matériau devant être enlevé par passe. Astuces : • • • pour de multiples itérations, je crois que si une pente tombe en dessous de la pente d'érosion minimale (Min Erosion Slope), l'érosion n'affecte plus la zone. La valeur Material Loss est un peu trompeuse. 100 % de perte ne signifie pas, mettre cette valeur à la hauteur la plus basse. Au lieu de cela, elle signifie quelque chose comme, mettre cette valeur à la hauteur voisine la plus basse. c'est un filtre très efficace qui enlève rapidement de grandes quantités de matériaux. 3.2.1.1.1.7 Hydraulic Erosion Table 35 : Hydraulic Erosion • • • Scale – pas d'effet Iterations (0..50) – détermine le nombre de passe d'érosion à effectuer. Control points – pas d'effet Astuces : • • c'est l'un de ces cas où avoir accès au code raccourcit considérablement les recherches. La Scale (filter) est passée à la méthode d'érosion, mais n'est pas utilisée. Ainsi, quelles que soient les modifications effectuées dessus, elles sont ignorées. Puisque les points de contrôle font partie du même mécanisme, vous pouvez aussi les ignorer. La seule chose à modifier est les iterations. ce gentil petit filtre semble remplir une obligation. Éroder les canaux, ou points bas, entre les collines abruptes. Je ne suis pas sûr qu'il érode aussi les bassins larges et plats, mais les effets ne sont pas visibles. Vous devez admirer les personnes qui ont codé ceci. Écrire un algorithme qui a pour but d'éroder des éléments spécifiques du terrain. Brillant ! 3.2.1.1.1.8 Blend Table 36 : Blend 80 / 223 Documentation de Torque V1.3.x Les paramètres de ce filtre modifient l'équation au-dessus du bouton Apply. Souvenez-vous juste que la source A est toujours l'opération précédente à ce Blend (mélange) (oui, il peut être y a voir un mélange de mélange de... bien, vous avez l'idée). J'ai reproduit, ciaprès, quelques petites expérimentations originellement effectuées par Zear pour montrer les capacités de ce filtre. Étape 1 Min Height : 20 Height Range : 200 Water Level : 0 Étape 2 Hill Frequency : 1 Roughness : 0.000 Details : Very Low Seed : 2080079341 Étape 3 Hill Frequency : 24 Roughness : 0.000 Details : Very High Seed : 1588197333 Étape 4 Factor : 0.358 Source B : 1 Operation : Max 3.2.1.1.1.9 Loading A Bitmap 81 / 223 Documentation de Torque V1.3.x J'ai volontairement reporté la discussion sur le chargement de nos propres images jusqu'à maintenant. De toutes les questions posées dans les forums, une des plus répétées est « Comment puis-je charger une image comme mon terrain ? ». Comme vous pouvez l'imaginer, ceci est relativement simple. Malheureusement, les versions antérieures à la 1.3 de Torque ne peuvent pas faire cela. Vous devez effectuer les modifications suivantes : • • localiser le répertoire : example\common\editor créer un nouveau sous-répertoire nommé : heightScripts (peut être tout en minuscules pour Unix) À partir de maintenant, si vous voulez utiliser une image bitmap pour votre terrain, copiez-la juste dans le répertoire example\common\editor avant de lancer le SDK et elle sera disponible. Je dis avant, car le SDK construit une liste des fichiers de ce répertoire lorsqu'il démarre, ainsi ceux ajoutés après ne seront pas vus. Veuillez noter, bien que le chargement d'un bitmap semble impliquer un BMP, vous ne pouvez utiliser que des fichiers PNG. 3.2.1.2 Éditeur de texture de terrain (Terrain Texture Editor) Lancement de l'éditeur de texture : 1. Lancez l'éditeur de mission en appuyant sur F11 2. Lancez l'éditeur de terraformation en appuyant F8 3.2.1.2.1 Fenêtre de prévisualisation d'éditeur de texture Après le terraformeur, l'éditeur de texture est probablement le second outil le plus compliqué dans l'éditeur de mission. À nouveau, nous sommes face à un tableau d'opérations pouvant être réalisées, basées sur divers facteurs et paramètres. Quand tout est dit et fait, le but principal de cet outil est de nous permettre de placer des textures sur notre terrain via la sélection d'algorithmes et de calculs. Le résultat final de ce placement peut être un paysage à l'aspect très naturel ou bien artificiel. Comme le terraformeur, nous avons la fenêtre de prévisualisation, l'arbre des opérations, et la fenêtre de paramétrage. En plus, nous avons une liste de textures, blottie entre la fenêtre de paramétrage et l'arbre des opérations. 3.2.1.2.2 Liste des textures (chargement des textures) Avant de pouvoir texturer notre terrain, nous devons décider quelles textures feront partie de notre palette. Pour charger un terrain, cliquez simplement sur le bouton Add Material et sélectionnez un terrain dans la boîte de dialogue apparaissant : L'éditeur de texture place notre texture en couches. La première (la plus sur le dessus) texture dans la liste des textures est la couche de base. Ceci est la texture qui est visible si aucune autre texture n'est appliquée sur un point su terrain. Dans ce cas, nous avons sélectionné la texture grass (herbe) dans notre base de textures : 82 / 223 Documentation de Torque V1.3.x Les matériaux ajoutés ultérieurement sont toujours placés à la fin de la liste. Ces textures sont appliquées suivant un algorithme et des paramètres (ou Placement Operations) : Dans le cas où deux textures (en plus de la texture de base) sont appliquées sur le même pixel de terrain, elles sont mélangées. 3.2.1.2.3 Opérations de l'éditeur de textures 3.2.1.2.3.1 Fractal Distortion (filtre de base) Table 37 : Fractal Distortion Chaque texture a un filtre de base appelé Fractal Distorsion. Le but de ce filtre est de donner un placement aléatoire des textures. L'interface est très similaire au générateur fBm du terraformeur. La différence majeure est l'interface d'échelle. Pour être honnête, je n'ai pas réellement d'indices quant à la fonction de ce dispositif dans ce contexte, mais je peux le manipuler. Je devine que les points de contrôle sont le niveau de détail et que l'échelle verticale donne la quantité des textures antérieures montrées au travers de cette texture après mélange. C'est-à-dire, si un point est en bas, 100 % de la texture précédente est montré au travers de cette texture (cette texture n'est pas appliquée) et si un point est en haut, 0% de la texture précédente est montrée au travers de la texture. 3.2.1.2.3.2 Place by Fractal Table 38 : Place by Fractal À nouveau, je suis embarrassé par la fonction exacte de ce filtre. Il ressemble au filtre Fractal Distortion avec en plus une case à cocher indiquant que nous pouvons ignorer le filtre Distortion. Je pense qu'il y a ici quelques histoires sinon, pourquoi les concepteurs fourniraient-ils deux filtres fractals ? Bien, vos distances varieront avec ce filtre et le précédent. Je vous suggère de les expérimenter et de voir ce que vous obtenez. À mon avis, les filtres suivants sont plus intéressants pour ajouter des effets spécifiques de texture. 3.2.1.2.3.3 Place by Height Table 39 : Place by Height 83 / 223 Documentation de Torque V1.3.x C'était le premier filtre qui a réellement un sens pour moi lorsque je le regarde. Le principe de ce filtre est simple. De base, il place des textures sur certaines plages d'élévation et les mélange en se basant sur le paramétrage vertical pour cette plage. Je montrerai le résultat de ceci dans les exemples plus loin. 3.2.1.2.3.4 Place by Slope Table 40 : Place by Slope Comme avec le filtre Height, ce filtre est relativement clair. Le côté gauche de l'échelle représente un terrain moins raide et le côté droit représente un terrain plus raide. À nouveau, l'échelle verticale est le facteur de mélange. 3.2.1.2.3.5 Place by Water Lever Table 41 : Place by Water Lever Ce dernier filtre nous permet de placer une texture au niveau ou en dessous du niveau d'eau que nous avons initialisé dans notre terraformeur. Ceci est utile si vous construisez une île ou avez un grand lac, mais je vous suggère de l'éviter. Au lieu de cela, pour de plus petites eaux superficielles, vous pouvez utiliser le peintre de texture (Texture Painter), dont nous parlerons bientôt. Puisque'une image vaut mieux que de longs discours, j'inclus quelques images d'exemple de l'utilisation de l'éditeur de textures. 3.2.1.2.3.6 Exemples 84 / 223 Documentation de Torque V1.3.x Couche à base d'herbe seulement. Couche à base d'herbe avec texture detail1 placée par Fractal. Couche à base d'herbe avec detail1 appliquée par Height. Notez que le paramètre de hauteur sert à placer la texture seulement sur les plages d'élévation les plus élevées. 85 / 223 Documentation de Torque V1.3.x Base d'herbe avec detail1 appliquée par inclinaison (Slope). Notez que le paramètre d'inclinaison sert à placer la texture seulement sur les zones les moins pentues (les plus plates). Base d'herbe avec detail1 et patchy appliquées à la même élévation (par hauteur). Notez le mélange de detail1 et de patchy. 3.2.1.3 Peintre de texture de terrain (Terrain Painter) Lancement du peintre de texture : 1. Lancez l'éditeur de mission en appuyant sur F11 2. Sélectionnez Texture Painter dans le menu Window 3.2.1.3.1 Examen du peintre de terrain Le dernier des outils que nous examinerons dans cette section est le peintre (Painter). Parmi tous ces outils, c'est probablement le plus simple. Si vous avez chargé avec succès le peintre, vous verrez quelque chose comme l'image plus loin. Maintenant, si vous avez utilisé n'importe quel outil comme WorlCraft, Wally, ou n'importe quel autre outil de création de contenu, vous serez familiarisé avec le concept de palette de peintre (Painter Pallet). 3.2.1.3.2 La palette Actuellement, la palette est limitée à 6 textures. En outre, la palette de textures doit être chargée dans le sens horaire. En d'autres mots, si vous essayez maintenant de cliquer sur le bouton Add dans le coin supérieur droit rien ne devrait se passer. Essayez de cliquer sur le bouton Add au milieu à gauche. Chargez la texture WeirdTerrain.png. 86 / 223 Documentation de Torque V1.3.x Lorsque vous cliquez soit sur un bouton Add ou Change, le dialogue Load File apparaîtra. Si vous jetez un coup d'œil rapide aux chemins affichés dans le dialogue, il deviendra clair que pour qu'une texture soit disponible, il est nécessaire qu'elle soit dans le répertoire data/terrains. Vous pouvez créer des répertoires dessous et l'outil trouvera vos textures dedans. L'outil trouvera automatiquement les fichiers dans l'un des deux formats suivants : • Portable Network Graphics (*.png) • JPEG (*.jpg) Je vous suggère fortement d'utiliser les fichiers PNG. Ainsi, vous éviterez les problèmes des JPEG. En outre, vous devrez suivre strictement les règles concernant les dimensions et les couleurs contenues dans vos fichiers graphiques. Dimension Suggéré : 256x256 pixels Requise : puissance de 2 et ratio inférieur à 16:1 (c'est-à-dire que la longueur doit être inférieure ou égale à 16 fois la largeur et vice versa) Densité DPI ou PPI Suggéré : 72 Nombre de bits / Couleurs Suggéré : 24 / 16 millions Couche alpha Suggéré : aucune Sur le côté droit de l'écran, vous devriez voir une fenêtre à l'aspect similaire à ceci. Actuellement, il y a deux textures chargées sur les six possibles. Le but de cette fenêtre est d'agir comme une sorte de palettes de peintre pour les textures. Simplement, en cliquant sur une texture chargée, vous pouvez utiliser cette texture pour peindre le terrain avec la brosse maintenant familière. Comme avec l'éditeur de terrain, vous pouvez changer la forme, la taille et la dureté de la brosse. Dans ce cas, la dureté affectera le mélange. Une brosse plus douce fournit des touches plus douces, donc la nouvelle texture est moins appliquée à chaque fois, et ainsi la texture du dessous est plus visible. Essayez. Cliquez sur la texture WeirdTerrain et peignez... Chouette, non ? 87 / 223 Documentation de Torque V1.3.x 4 Torque script Ce chapitre est adapté du guide exceptionnel « Essential Guide Torque Game Engine (EGTGE) » de Edward Maurina. L'EGTGE devrait être lu par tous les développeurs sérieux de Torque. Ce chapitre propose une introduction à TorqueScript. Vous ne serez pas un maître TorqueScript après avec simplement lu ce chapitre – cela prend du temps et de la pratique. Mais vous aurez un bon aperçu de la structuration de TorqueScript et du fonctionnement général. Vous serez familiarisé avec le jeu d'outils offert par TorqueScript pour vous aider à créer votre jeu. Avec ces connaissances en main, vous serez prêt pour décoller et commencer à apprendre comment utiliser au mieux les outils de TorqueScript. Il y a beaucoup de documentations supplémentaires et de tutoriels pour vous aider après la fin de la lecture de ce livre. Regardez la page des tutoriels de Torque chez GarageGames pour plus d'information. Il est présumé dans la suite que vous êtes familiarisé avec certains concepts de programmation. Vous n'avez pas besoin d'être un gourou, et vous n'avez pas besoin non plus de connaître les spécificités d'un langage comme le C++, mais vous devrez être familier avec les bases de la programmation d'un ordinateur pour tirer le plus de ce qui est offert ici. 4.1 Concepts et terminologies de TorqueScript 4.1.1 Script ou pas script ? Comme vous devez probablement le savoir, tous les moteurs de jeux complets et modernes offrent une méthode de programmation du comportement du jeu via un langage de script. Mais, qu'est-ce exactement un langage de script ? Que pouvez-vous faire avec des scripts ? Pourquoi sont-ils autant utilisés dans le développement moderne de jeux ? Les langages de script sont juste des langages de programmation qui permettent une écriture facile du code. Si vous regardez à l'Histoire des langages de programmation, vous pourrez voir une progression brutale à partir de langages de très bas niveau qui sont difficiles à lire et écrire, vers les langages de haut niveau qui sont beaucoup plus faciles à appréhender. Par exemple, le langage Assembleur était disponible bien avant le C++. L'Assembleur est très difficile à lire et à écrire pour la plupart des gens, et bien que vous puissiez écrire la plupart des programmes soit en C++, soit en Assembleur, le C++ est habituellement un meilleur choix depuis qu'il est beaucoup plus facile à écrire, tester, déboguer et maintenir. Le mauvais côté est que le code C++ s'exécute parfois plus lentement que l'Assembleur. De même, les langages de script offrent certains avantages par rapport aux langages plus anciens comme C++, et peuvent réellement être considérés comme une étape supplémentaire dans la progression des langages de programmation. En fait, beaucoup de langages ont un aspect très similaire au C++, mais vous permettent d'écrire du code sans vous inquiéter des détails tels que le type des données ou la gestion de la mémoire. Les langages de script vous permettent aussi de modifier votre programme sans devoir recompiler le code. Ceci peut être un avantage majeur. Cependant, le code de script ne s'exécute pas aussi vite que le code C++. Après tout cela, il devrait être aisé de voir pourquoi les langages de script sont utilisés aussi intensément dans les jeux modernes. En effet, maintenant, la plupart des programmeurs de jeux modernes écrivent du code avec l'objectif suivant : si vous avez une fonctionnalité donnée à écrire, commencez par tenter de l'écrire en script, et seulement si cela est absolument nécessaire, écrivez-le en C++. Les programmeurs pensent la même chose sur la différence entre le C++ et l'Assembleur : entre ces deux choix, la majorité du code devrait être en C++, l'Assembleur devant être utilisé seulement où cela est absolument nécessaire. Ceci est la vue générale. Ci-après, vous trouverez quelques aspects plus spécifiques où la facilité, la flexibilité et la rapidité d'écriture des scripts peuvent réellement être avantageuses : • Prototypage – durant le développement de votre jeu, vous aurez souvent besoin de tester vos idées. De nouveaux dispositifs de gameplay peuvent fonctionner, ou des dispositifs dans le concept original peuvent ne pas fonctionner aussi bien que prévu et nécessiteront d'être modifiés 88 / 223 Documentation de Torque V1.3.x ou remplacés. Pour être efficace, vous aurez besoin de la possibilité de tester rapidement toutes ces idées ainsi, vous pouvez décider de conserver ou modifier chacune d'elles. La création de ces tests rapides est appelée le prototypage (prototyping). Les scripts sont doués pour le prototypage, car ils sont aussi rapides à écrire qu'à tester et modifier. Après le prototypage sous forme de script, les fonctionnalités aux performances critiques peuvent être portées en C++ pour une intégration finale dans le jeu. • Débogage – les scripts peuvent être doués aussi pour le débogage. Depuis que les scripts sont aisément modifiables à la volée, vous pouvez identifier les problèmes, les modifier, et les tester à nouveau sans avoir à les recompiler. Les scripts peuvent aussi être utilisés pour créer rapidement des unités de test qui mettent l'accent sur d'autres morceaux de code pour identifier les problèmes. • Personnalisation et ajustement de jeu – l'aspect d'une interface de jeu et beaucoup de ses mécanismes de gameplay habituellement se font au travers de touches successives et de révisions durant le cours du développement. Ainsi, il est meilleur de placer la majoriré du code relatif à cette partie dans un script. Ceci aide à tester rapidement différents aspects et comportements du gameplay, comme mentionné dans le point sur le prototypage. Il y a un côté bénéfique de développer votre jeu de cette manière : avoir un code relatif à votre interface et votre gameplay sous forme de script permet à vos joueurs de personnaliser votre jeu à leur goût (mais seulement pour les extensions que vous leur autorisez, dans la version officielle de votre jeu). En outre, ces types de modification de script sont la base de beaucoup de modifications (mod) partielles de jeu. Les mods partiels sont très populaires dans des jeux comme Unreal, Quake et Tribes. En prenant Tribes 2 comme exemple, War 2002, Renegades, et Team Aerial Combat sont tous basés sur des scripts de mods partiels. Côté du codage, les mods partiels peuvent être vraiment très simples à implémenter lorsqu'on travaille avec des jeux incorporants des langages de script et les utilise pour une grande du code du jeu. L'implémentation de votre jeu d'une telle manière peut évidemment être très attractive pour les joueurs potentiels qui sont intéressés pour joueur ou modifier les mods. • Mods globaux – tout comme les mods partiels, les mods globaux de jeu sont très populaires et sont également habituellement basés sur du codage de script. Les mods globaux changent complètement le jeu et l'aspect du jeu, contrairement aux mods partiels qui ne vont pas si loin. Les deux sont plus aisément réalisés dans les jeux incluant des langages de script. • Écriture de fonctionnalités aux performances non critiques – réellement, n'importe quelle partie de fonctionnalité qui n'a pas un gros impact sur les performances peut être codée en script. L'écriture de fonctions de rendu graphique en script n'est pas une bonne idée, mais l'est pour l'écriture de réponses GUI et la plupart des fonctionnalités de gameplay. La création de scripts a un sens dans beaucoup plus de situations. L'inclusion de langages de script est une caractéristique puissance des moteurs de jeux modernes, et les développeurs sont avisés de tirer avantage des scripts autant que possible. 4.1.2 Fonctionnalités nécessaires Si vous acceptez que les scripts sont utiles, que devez-vous regarder dans un langage de script ? Quelles fonctionnalités doit-il fournir ? Au minimum, un langage de script utilisé dans un jeu doit fournir les fonctionnalités suivantes : • Fonctionnalités de programmation de base – le langage de script doit fournir toutes les fonctionnalités communes de base des langages de programmation modernes, telles que : types de variables puissants, opérations de base (addition, soustraction...), commandes de contrôle de base (if-then-else, for, while...), et sous-programmes (fonctions, inclusion de fichiers). • Accès à la structure du moteur – ceci est une fonctionnalité critique. Pour un environnement de script d'un moteur de jeu, il doit fournir une interface pour manipuler les fonctionnalités et les structures du cœur du moteur. Le système de scripts doit permettre d'accéder aux systèmes de 89 / 223 Documentation de Torque V1.3.x rendu, audio, physiques, intelligence artificielle, et entrée/sortie. Quelques autres fonctionnalités (très) agréables à avoir : • Syntaxe familière et cohérente – idéalement, la syntaxe d'un langage de script est familière, signifiant qu'elle est similaire à la syntaxe d'un langage familier à beaucoup de programmeurs, par exemple le C ou le C++. De même, la syntaxe est cohérente avec le langage connu, signifiant que les règles, appliquées dans le langage de programmation familier, sont les mêmes que celles du langage de script. • Fonctionnalités orientées objet – la programmation orientée objet a été une révolution dans l'art et la science des technologies de programmation. Les langages de scripts qui fournissent des fonctionnalités orientées objet offrent beaucoup d'avantages, incluant : • • • Encapsulation – fournit un moyen de limitation d'accès au code et aux données. Héritage – fournit un moyen de création de nouveaux objets à partir des objets du moteur et/ou des objets scriptés. Polymorphisme – nous permet de surcharger le comportement du code d'objet dérivé, si l'objet est dérivé des objets du moteur ou des autres objets scriptés. • Chargement et dimensionnement « à la demande » – pourquoi avoir tout le code en mémoire en même temps alors qu'il peut être chargé lorsque cela est nécessaire ? Outre la préservation de la mémoire, les langages de script qui permettent le chargement et déchargement dynamique de parties de code, facilitent également la surcharge d'une fonctionnalité d'un programme « à la volée ». • Moyens d'accélaration du code scripté – le code scripté n'est pas habituellement compilé, il est simplement interprété. Une fonctionnalité, que fournit beaucoup de langage de script commun (PERL, TCL, VB Script, Java), est la possibilité de « compiler » le script en pcode. Ce pcode est « exécuté » via une machine virtuelle. Les avantages de cela sont la taille et la vitesse. Le Pcode est (normalement) plus petit et s'exécute plus rapidement que le code interprété. 4.1.3 Que dire sur TorqueScript ? Bien, assez de généralités. À quoi ressemble le langage de script de Torque ? TorqueScript est un langage très puissant et flexible avec une syntaxe similaire au C++. Il fournit toutes les caractéristiques du dessus, incluant celles de la liste « des fonctionnalités agréables à avoir ». Les sections suivantes décriront toutes ces fonctionnalités et fourniront des exemples pour clarifier les concepts. En plus, il y a les références de script dans l'annexe. 4.1.4 La console et les scripts simples Les pages à venir détaillent les caractéristiques spécifiques de Torque. Durant les explications, beaucoup d'exemples sont fournis. Les exemples de code seront montrés d'une des deux méthodes : • • exemples à tester directement dans la console, en ligne de commandes. chargement d'un fichier de script via la console, et exécution de celui-ci. Bien, comment utiliser la console ? Facile. Premièrement, lancez l'application de démonstration de Torque, et tapez sur la touche tilde « ~ » (ou cliquez sur l'icône console). La console apparaîtra ainsi : 90 / 223 Documentation de Torque V1.3.x Vous verrez un tas de commandes echo() dans ce chapitre. Nous utilisons la commande echo() dans un but de test – il affiche des valeurs dans la console. echo() a la syntaxe suivante : echo(string0 [, string1 [,...,[string n]]]); Tout au long de ce chapitre, les commandes qui apparaîtront dans une boite comme ci-dessous montrant des lignes de code TorqueScript. Une ligne seule de commandes peut être copiée et collée directement dans la console. Essayez ceci : echo("Torque Rocks"); echo(1+1); Si vous saisissez ce code dans la console et appuyez sur <Entrée>, vous verrez s'afficher « Torque Rocks » et « 2 ». Tout ce qui est placé entre les parenthèses de la commande echo() est affiché dans la console. 4.2 Le langage de TorqueScript 4.2.1 Caractéristiques du langage • Insensibilité au typage – dans TorqueScript, les types des variables sont convertis si nécessaire et peuvent être interchangés. TorqueScript fournit plusieurs types litéraux de base, qui sont décrits plus loin dans ce chapitre. If("1.2" == 1.2) { echo("Identique – TorqueScript est insensible au type"); } else { echo("Différent – quoi ?"); } Le code précédent affichera « Identique – TorqueScript est insensible au type ». • Insensibilité à la casse – TorqueScript ignore la casse lors de l'interprétation des noms de variables et de fonctions. $a = "Un exemple"; echo($a); echo($A); Ce code affichera « Un exemple » deux fois. • Terminaison de commande – Les commandes sont terminées par un point-virgule (;) comme 91 / 223 Documentation de Torque V1.3.x dans beaucoup de langages modernes (C++, Java, Javascript, etc.). $a = "Ceci est une commande"; Si vous n'incluez pas le point-virgule à la fin d'une commande TorqueScript, une erreur sera affichée dans la console. • Support complet des opérateurs – la liste complète des opérateurs de TorqueScript est donnée en annexe. TorqueScript fournit tous les opérateurs communs de base de la plupart des langages de programmation, avec quelques opérateurs plus avancés. • Support complet des structures de contrôle – comme avec n'importe quel langage robuste, TorqueScript fournit les structures de programmation standards : if-then-else, for, while et switch. for($a=0; $a <5; $a++) { echo($a); } • Fonctions – TorqueScript fournit la possibilité de créer des fonctions avec la capacité optionnelle de retourner des valeurs. Les paramètres sont passés par valeur ou par référence (voir la section sur les fonctions pour avoir une description détaillée et des exemples). • Fourniture de l'héritage et du polymorphisme – TorqueScript vous permet d'hériter des objets du moteur et, par conséquent, étendre et surcharger des méthodes d'objet (voir plus loin pour une description détaillée et des exemples). • Fourniture d'espaces de nommage – comme en C++, TorqueScript supporte le concept d'espaces de nommage (Namespace18). Les espaces de nommage sont utilisés pour localiser des noms et des identifiants afin d'éviter des « collisions ». Cela signifie, par exemple, que vous pouvez avoir deux fonctions différentes nommées doIt() qui existent dans deux espaces de nommage séparés, mais qui sont utilisés dans le même code (voir la section sur les espaces de nommage pour une description détaillée et des exemples). • Fourniture du chargement et déchargement de fonctions à la demande – TorqueScript supporte une caractéristique très intéressante, qui vous permet de charger et décharger des fonctions si nécessaire (voir la section sur les packages pour une description détaillée et des exemples). • Compilation et exécution de PCODE – le moteur de TorqueScript compile les scripts avant de les exécuter. Cela augmente ainsi la vitesse d'exécution. De même, TorqueScript fournit le nécessaire pour diagnostiquer les erreurs dans les scripts. Avec cet aperçu des caractéristiques de TorqueScript, nous pouvons maintenant parler en détail du fonctionnement de TorqueScript. Nous commencerons par examiner comment TorqueScript gère les variables, opérateurs et commandes de contrôle de base. Ces points étant couverts, nous irons regarder en détail les fonctionnalités plus avancées de TorqueScript. 4.2.2 Les variables Les variables dans TorqueScript sont de deux types : locale et globale. Les variables locales sont temporaires, signifiant qu'elles sont automatiquement détruites lorsqu'elles sortent du contexte (scope). Et qu'est-ce qu'un contexte ? Un « contexte » est un terme utilisé pour référencer le bloc de code dans lequel une variable est définie. Par exemple, si nous avons une fonction, et y déclarons une variable locale, celle-ci sera détruite dès que la fonction a été exécutée. Lorsque cela survient, nous disons que la variable est 18En informatique, un espace de nommage (namespace en anglais) est une notion permettant de désambiguïser des termes qui pourraient être homonymes sans cela. Un espace de nommage est matérialisé par un préfixe identifiant de manière unique la signification d'un terme. Au sein d'un même espace de nommage, il n'y a pas d'homonyme. (Wikipédia) 92 / 223 Documentation de Torque V1.3.x « sortie du contexte ». Ainsi, les variables locales existent seulement dans leur contexte local – la fonction ou le bloc de code où elles sont définies. Un morceau de code à l'intérieur d'une fonction différente ne pourra pas voir la variable locale. Les variables globales, quant à elles, sont permanentes et existent dans la totalité du programme dans lequel elles sont définies. TorqueScript marque spécifiquement les variables locales et globales avec des caractères spéciaux, ainsi elles sont plus faciles à identifier. La syntaxe est la suivante : %var_locale = valeur; $var_globale = valeur2; Dans TorqueScript, les variables n'ont pas besoin d'être déclarées avant leur utilisation. Si un morceau de code tente d'évaluer la valeur d'une variable n'ayant pas été créée précédemment, TorqueScript créera automatiquement la variable : for(0; %a < 5; %a++) { echo(%a); } echo(%a); Jetons un coup d'œil sur ce que fait ce code : 1) Lors du premier passage dans la boucle, le code crée une nouvelle variable nommée %a. Il doit faire ainsi, car %a n'a pas encore été créé lorsque la boucle tente de l'utiliser pour la première fois. 2) La commande echo() dans la boucle affichera la valeur contenue dans la variable %a quatre fois, affichant les valeurs 0, 1, 2, 3 et 4 pendant que la boucle réitère et que la valeur %a de augmente. 3) Après la fin de la boucle, %a s'affichera une fois encore, au travers de la ligne après la boucle. Ceci est une description de base du fonctionnement des variables locales et globales dans TorqueScript. Maintenant, en créant une nouvelle variable, nous savons ce qui se produira si nous la faisons locale ou globale, mais quels noms seront autorisés par TorqueScript pour nos variables ? Les noms de variables peuvent contenir n'importe quel nombre de caractères alphanumériques (a..z, A..Z, 0..9), aussi bien que le caractère tiret bas (_) appel aussi underscore. Cependant, le premier caractère du nom d'une variable ne peut pas commencer par un nombre. Vous pouvez terminer les noms des variables par un nombre, mais si vous faites cela, vous devez faire très attention avec les noms des tableaux. Pour plus d'information, référencez-vous à la section sur les tableaux. Pour finir, les variables locales et globales peuvent avoir le même nom, mais contenir des valeurs différentes. $a="EGT"; for(0; %a < 4; %a++) { echo($a SPC %a); } Ce code affichera « EGT 0 », « EGT 1 », « EGT 2 » et « EGT 3 ». 4.2.2.1 Les types de données TorqueScript supporte implicitement plusieurs types de données de variable : nombres, chaînes, booléens, tableaux et vecteurs. Chaque type est maintenant détaillé. 4.2.2.1.1 Les nombres 123 1.234 Entier (Integer) Virgule flottante (Floating point) 93 / 223 Documentation de Torque V1.3.x 1234e-3 0xc001 Notation scientifique Hexadécimal Rien de mystérieux ici. TorqueScript gère vos types numériques standards. 4.2.2.1.2 Les chaînes "abcd" Chaîne (String) 'abcd' Chaîne marquée (Tagged string) Les chaînes standards, entre guillemets (double-quotes), se comportent comme vous escomptez. Essayez ces exemples : echo("Bonjour !"); echo("1.5" + "0.5"); Les chaînes apparaissant entre apostrophes (quotes), 'abcd', sont traitées de manière spéciale par TorqueScript. Ces chaînes sont appelées « chaînes marquées », et sont spéciales dans le fait qu'elles contiennent des données de chaînes, mais aussi ont un marqueur numérique spécial associé. Les chaînes marquées sont utilisées pour envoyer des données de chaîne au travers du réseau. La valeur d'une chaîne marquée est envoyée une seule fois, indépendamment du nombre de fois réel de l'envoi. Dans les envois suivants, seul le marqueur est envoyé. Les valeurs marquées doivent être démarquées lors de l'affichage. Essayez ces exemples : $a="Ceci est $b='Ceci est echo("Chaîne echo("Chaîne echo("Chaîne une chaîne normale"; une chaîne marquée'; normale : " $a); marquée : " $b); démarquée : " detag('$b')); Note : vous pouvez trouver étrange que la dernière ligne affiche un blanc. Ceci est, car bien que nous ayons créé la chaîne marquée, elle ne nous a pas été transmise. Vous ne pouvez démarquer qu'une chaîne marquée qui vous a été transmise. 4.2.2.1.3 Les opérateurs de chaînes @ TAB SPC NL Concaténation19 de deux chaînes Concaténation avec tabulation Concaténation avec espace Nouvelle ligne Concaténer deux chaînes signifie, simplement, de les coller ensemble. Par exemple, si nous concaténons les chaînes "Bonjour " et "à tous", nous obtiendrons une chaîne plus grande contenant "Bonjour à tous". La syntaxe de base pour ces opérateurs de chaîne est : "chaine 1" op "chaine 2" où op est un opérateur de chaîne. Par exemple : echo("Bonjour" echo("Bonjour" echo("Bonjour" echo("Bonjour" @ "à tous"); TAB "à tous"); SPC "à tous"); NL "à tous"); Pour avoir une idée concrète du fonctionnement de ces opérateurs, collez les lignes précédentes dans la console et observez les différences d'affichage. 19 Informellement, en programmation, on appelle la concaténation de deux chaînes de caractères, la chaîne formée de ces deux chaînes mises bout à bout. (Wikipédia) 94 / 223 Documentation de Torque V1.3.x Il y a un dernier domaine à savoir sur le fonctionnement des chaînes dans TorqueScript : les séquences d'échappement (escape). 4.2.2.1.4 Les séquences d'échappement \n \r \t \c0...\c9 \cr \cp \co \xhh \\ Nouvelle ligne Retour chariot (carrriage return) Tabulation (tab) Séquence de colorisation de texte Retour à la couleur par défaut Pousse (push) la couleur courante sur la pile Récupère (pop) la couleur de la pile Code ASCII à deux chiffres hexadécimaux Barre oblique inversée ou antislash (backslash) Comme en C, TorqueScript vous permet de créer une nouvelle ligne ou une tabulation en utilisant le caractère antislash qui a fait ses preuves. Ce sont les « séquences d'échappement ». Elles sont utilisées pour indiquer au système de traitement des chaînes qu'un caractère spécial est en cours de lecture. En plus, pour les données affichées dans la console et l'interface GUI, vous pouvez les coloriser en utilisant '\cn', où n est une valeur entre 0 et 9, représentant un jeu prédéfini de couleurs. echo("\c2ERREUR !!!\c0 ==> Zut"); Le code précédent affiche la ligne "ERREUR !!! ==> Zut" avec la première partie en rouge, et le reste en noir. Entrer dans les détails sur la colorisation est en dehors du cadre de ce chapitre, mais une petite expérimentation vous aidera à comprendre comment cela fonctionne. 4.2.2.1.5 Les booléens Comme la plupart des langages de programmation, TorqueScript supporte également les booléens. Les nombres booléens n'ont que deux valeurs possibles – true (vrai) ou false (faux) true 1 false 0 Encore, comme dans beaucoup de langages de programmation, la constante true est associée au nombre 1 dans TorqueScript, et la constante false au nombre 0. Les nombres, les chaînes et les booléens, sont les types de données de base dans beaucoup de langages de programmation, et TorqueScript les supporte tous. Ensuite, nous regarderons les types de données de variable de plus haut niveau : les tableaux et les vecteurs. 4.2.2.1.6 Les tableaux $MyArray[n] $MyMultiArray[m,n] $MyMultiArray[m_n] simple dimension multidimensions multidimensions TorqueScript est extrêmement flexible avec les tableaux. Beaucoup de langages de script sont plus flexibles avec les tableaux que les langages compilés comme le C++, mais TorqueScript est même plus flexible que la plupart des langages de script. Toute cette flexibilité peut être déroutante, et la compréhension de la gestion par TorqueScript des tableaux peut désarçonner les gens. Par exemple, il y a une idée fausse qui veut que TorqueScript ne supporte par les tableaux multidimensionnels. Ceci n'est pas vrai, comme le montrent les exemples précédents. La raison pour laquelle beaucoup de monde est embarrassé avec les tableaux multidimensionnels dans TorqueScript est qu'il y a plusieurs manières d'adresser les tableaux. Comme vous pouvez le voir, vous pouvez séparer les indices dimensionnels (m et n, précédemment) avec une virgule, ou même un underscore (_). 95 / 223 Documentation de Torque V1.3.x Voici deux fonctionnalités intéressantes de plus sur la gestion des tableaux par TorqueScript : 1) $a et $a[0] sont des variables distinctes et séparées. Il est recommandé d'utiliser une convention de nommage claire lorsque vous gérez un tableau : $a = 5; $a[0] = 6; echo("$a == ", $a); echo("$a[0] == ", $a[0]); Exécutez ce code, et vous verrez que $a et $a[0] sont distincts. 2) $MyArray0 et $MyArray[0] sont les mêmes. Ceci peut être surprenant, mais TorqueScript vous permet d'accéder aux indices de tableau sans utiliser la syntaxe commune des crochets []. De nouveau, il est recommandé d'utiliser une convention de nommage pour identifier les tableaux dans votre code. $aryMyArray[0] = "case 0"; echo($aryMyArray0); $aryMyArray[1] = "case 1"; echo($aryMyArray0); $aryMyArray[0,0] = "case 0-0"; echo($aryMyArray0_0); Tous les affichages du code précédent illustrent que TorqueScript traite les indices dans des crochets de la même manière que les indices accolés. Maintenant que nous avons une compréhension de base des tableaux, c'est le moment de s'occuper des vecteurs. 4.2.2.1.7 Les vecteurs "1.0 1.0 1.0 1.0" vecteur de 4 éléments Les vecteurs sont un type de données très utile qui sont utilisés dans tout TorqueScript. Par exemple, beaucoup de champs dans l'éditeur de monde sont constitués d'un jeu de 3 ou 4 valeurs numériques. Ils sont stockés et interprétés comme vecteurs. Il y a toute une série d'opérations de console pour la manipulation des vecteurs. En outre, les vecteurs sont utilisés comme entrée de beaucoup de méthodes de jeu. 4.2.3 Les opérateurs Une liste complète des opérateurs de TorqueScript peut être trouvée dans l'annexe de TorqueScript. Référezvous à l'annexe pour des informations détaillées. En général, les opérateurs de TorqueScript se comportent de manière très similaire aux opérateurs des langages dérivés du C. Il y a deux avertissements communément rencontrés lorsqu'on travaille avec les opérateurs de TorqueScript : • • Les opérateurs ++ et -- sont uniquement des opérateurs suffixes (c'est-à-dire ++%a; ne fonctionne pas, seulement %a++; est valide). Les comparaisons de chaînes ont la forme : $= !$= opérateur d'égalité de chaîne opérateur d'inégalité de chaîne Ce sont les opérateurs les plus couramment rencontrés dans TorqueScript. De nouveau, une référence complète peut être trouvée dans l'annexe. 4.2.4 Les commandes de contrôle 96 / 223 Documentation de Torque V1.3.x 4.2.4.1 Les structures de branchement Nous allons maintenant aborder les commandes de contrôle de TorqueScript – les structures de branchement et de boucle. TorqueScript supporte toutes les commandes de contrôle communes : • if-then-else – la structure générale de la commande if-then-else est : if(expression) { commandes; } else { commandes alternatives; } Choses à savoir : • Les accolades '{}' sont optionnelles s'il y a une seule ligne de commandes (beaucoup de programmeurs trouvent qu'il est plus clair de toujours utiliser les accolades). • Les commandes if-then-else multiples sont parfaitement autorisées (beaucoup de programmeurs trouvent que la commande switch est beaucoup plus facile à lire avec de grands blocs de code). • switch – la structure générale de la commande switch est : switch(expression) { case valeur0: commandes; break; case valeur1: commandes; break; ... case valeurN: commandes; break; default: commandes; }; Choses à savoir : • switch évalue (correctement) uniquement des numériques. Il y a une commande spéciale, 'switch$', pour les chaînes. • Les commandes break sont superflues. TorqueScript exécute uniquement les cas correspondants. • Dans TorqueScript, les commandes switch ne sont pas plus rapides que les commandes if-then-else. • switch$ – cette construction se comporte exactement comme la commande switch avec une exception importante : elle n'est que pour les chaînes. 4.2.4.2 Les structures de boucle • for – la structure générale d'une boucle for est : for(expression0; expression1; expression2) { commande(s); 97 / 223 Documentation de Torque V1.3.x } Par exemple : for(%count = 0; %count < 5; %count++) { echo(%count); } Comme vous pouvez le voir, ceci est identique à la boucle for-loop du C++. Note : il est hors propos dans ce chapitre d'essayer d'apprendre les bases de la programmation. Les programmeurs débutants devraient lire quelques tutoriels sur la programmation avant de tenter de parcourir ce chapitre. • while – la structure générale de la boucle while est : while(expression) { commande(s); } Voici un exemple explicite : %count = 0; while(%count < 5) { echo(%count); %count++; } Comme vous pouvez le constater, TorqueScript supporte le jeu standard des commandes de contrôle et les gère de manière très similaire aux langages comme le C++. 4.2.5 Les fonctions Les fonctions de base dans TorqueScript sont définies ainsi : function nom_fonction([arg0],...,[argn]) { commande(s); [return valeur;] } Voici un exemple : function echoRepeat(%echoString, %repeatCount) { for (%count = 0; %count < %repeatCount; %count++) { echo(%echoString); } } echoRepeat("Bonjour !",5); Le code ci-dessus affichera la chaîne "Bonjour !" cinq fois dans la console. Les fonctions de TorqueScript peuvent avoir n'importe quel nombre d'arguments, chacun séparé par une virgule. Les fonctions peuvent retournées une valeur en utilisant la commande return, comme en C++. Chose à savoir : 98 / 223 Documentation de Torque V1.3.x • • • Si vous définissez une fonction et lui donnez le même nom qu'une fonction précédemment définie, TorqueScript surchargera entièrement l'ancienne fonction. Ceci est une note importante : TorqueScript ne supporte le polymorphisme de fonction de la même manière que le C++. Cependant, TorqueScript fournit les package qui peuvent contourner ce problème. Si vous appelez une fonction et passez moins de paramètres que la définition de la fonction spécifiée, les paramètres omis seront considérés comme des chaînes vides. TorqueScript supporte la récursivité, et se comporte comme en C++. L'exemple suivant est une version récrite de la fonction echoRepeat() que nous avons vue précédemment, mais cette fois-ci, nous utilisons la récursivité à la place d'une boucle for. function echoRepeat(%echoString, %repeatCount) { if (%repeatCount >0) { echo(%echoString); echoRepeat(%echoString, %repeatCount--) } } echoRepeat("Bonjour !",5); 4.2.6 Les objets Après avoir couvert les bases du langage, il est temps d'examiner quelques détails plus intéressants de TorqueScript. Dans TorqueScript, chaque élément dans le monde du jeu est un objet, et tous les objets du monde du jeu peuvent être accédé via les scripts. Par exemple, Player, WheeledVehicle, Item, etc. sont tous accessibles via les scripts, bien qu'ils soient définis en C++. Les objets sont créés dans TorqueScript en utilisant la syntaxe suivante : // In TorqueScript %var = new ObjectType(Name : CopySource, arg0, ..., argn) { <datablock = DatablockIdentifier;> [existing_field0 = InitialValue0;] ... [existing_fieldM = InitialValueM;] [dynamic_field0 = InitialValue0;] ... [dynamic_fieldN = InitialValueN;] }; Cette syntaxe est plus simple qu'elle n'y paraît. Analysons-la : • • • • • • %var – est la variable où l'identifiant (handle) de l'objet sera stocké. new – est un mot-clef demandant au moteur de créer une instance du type d'objet indiqué. ObjetType – est n'importe quelle classe déclarée dans le moteur ou dans le script qui a été dérivée de SimObject ou d'une sous-classe de SimObject. Les objets dérivés de SimObject sont ce que nous appelons précédemment comme « objets du monde du jeu ». Name (optionnel) – est n'importe quelle expression s'évaluant comme une chaîne, qui sera utilisée comme nom de l'objet. CopySource (optionnel) – le nom d'un objet qui est préalablement défini quelque part dans un script. Les valeurs des champs existants seront copiées de CopySource vers le nouvel objet en cours de création. N'importe quels champs dynamiques définis dans CopySource seront également définis dans le nouvel objet, et leurs valeurs seront copiées. arg0, ..., argn (optionnel) – est une liste d'arguments séparés par des virgules pour le 99 / 223 Documentation de Torque V1.3.x • • • constructeur de classe (s'il en prend) datablock – beaucoup d'objets (ceux dérivés de GameBase, ou d'enfants de GameBase) requièrent des blocs de données pour initialiser les attributs spécifiques du nouvel objet. Les blocs de données (Datablock) sont abordés plus loin. existing_fieldM – en plus de l'initialisation des valeurs avec un datablock, vous pouvez aussi initialiser ici les membres de classe existants (champ). Note : afin de modifier un membre d'une classe définie en C++, le membre doit être exposé vers la Console. Ce concept est détaillé plus tard. dynamic_fieldN – pour finir, vous pouvez créer de nouveaux champs (qui n'existeront que dans un script) pour votre nouvel objet. Ceux-ci seront montrés comme champs dynamiques dans l'inspecteur de monde. Créons un objet n'utilisant pas de datablock, et un en possédant un : // créer un SimObject sans modification d'aucun champ. $objet_exemple = new SimObject(); // créer un SimObject avec champs dynamiques. $objet_exemple = new SimObject(); { un_nouveau_champ = "Bonjour !" } // créer un StaticShape en utilisant un bloc de données. Datablock StaticShapeData(MyFirstDataBlock) { shapeFile = "~/data/shapes/player/player.dts"; junkvar = "bonjour"; }; new StaticShape() { datablock = "MyFirstDataBlock"; position = "0.0 0.0 0.0"; rotation = "1 0 0 0"; scale = "1 1 1"; }; 4.2.6.1 Identifiants et noms Chaque objet dans le jeu est identifié et pisté via deux paramètres : • • Identifiant (handle)– chaque objet est assigné à un ID numérique unique depuis sa création. Ceci est généralement référencé comme l'identifiant de l'objet. Nom – en plus, tous les objets peuvent avoir un nom. Dans la plupart des cas, les identifiants et les noms peuvent être utilisés indifféremment pour référencer le même objet, mais la précaution est une règle. Les identifiants sont toujours uniques, tandis que de multiples objets peuvent avoir le même nom. Si vous avez de multiples objets avec le même nom, le référencement à ce nom trouvera un et seulement un des objets. 4.2.6.2 Champs et commandes Les objets de TorqueScript field (champ) et command (commande) sont les équivalents des objets membre et méthode du C++. Les objets instanciés via le script peuvent avoir des membres de données (référencé comme champs) et des méthodes fonctionnelles (référencées comme commandes). Afin d'accéder à un champ ou une commande d'objet, utilisez la notation standard « . », comme en C++ : // note : rien ici dans le code ne fonctionnera dans la console, car nous // utilisons des noms et des identifiants qui n'existent pas. 100 / 223 Documentation de Torque V1.3.x // Ce code sert juste à illustrer quelques concepts. // accès direct via l'identifiant 123.fied_name = valeur; 123.command_name(); // accès direct via le nom AName.field_name = valeur; Aname.command_name(); // accès indirect via une variable %AVar.field_name = valeur; %Avar.command_name(); Pour avoir une image du fonctionnement réel de ceci : 1. 2. 3. 4. Lancez le SDK (vous pouvez juste lancer la démonstration de Torque, si vous préférez) Lancez une des missions Démarrez l'inspecteur de monde (appuyez sur F11) Basculez en vue caméra (appuyez sur Alt+C) et sélectionnez le personnage (maintenez appuyer le bouton droit de la souris pour regarder autour, glissez la souris jusqu'à ce que le personnage soit visible. Relâchez le bouton droit de la souris et cliquez sur le personnage). 5. Donnez un nom à votre personnage, du style « monGars », sans les guillemets, dans la boîte de texte derrière le bouton Apply, et cliquez sur ce dernier. 6. Ouvrez la console (appuyez sur la touche ~) 7. Saisissez les lignes de code suivantes : $player_name = "monGars"; $player_id = $player_name.getID(); echo($player_name.position); echo($player_name.getID()); echo(monGars.getID()); 4.2.6.3 Champs dynamiques En plus des champs normaux, qui sont communs entre toutes les instances d'un type d'objet, TorqueScript vous permet de créer des champs dynamiques. Les champs dynamiques sont associés avec une instance unique d'un objet et peuvent être ajoutés ou supprimés à volonté. L'ajout d'un champ dynamique dans TorqueScript est automatique. Si vous essayez de lire un champ d'objet et que le champ n'est pas trouvé, TorqueScript retournera simplement une chaîne vide, et aucun champ dynamique ne sera créé. Cependant, si vous essayez d'écrire dans un champ d'objet qui n'existe pas, TorqueScript créera automatiquement un champ dynamique correspondant pour l'objet, et lui assignera la valeur que vous tentez d'écrire. // une nouvelle variable ne sera pas créée car nous tentons seulement // de la lire. echo($player_id.new_year); // new_year2 sera créée et initialisée à "Bonjour" $player_id.new_var2 = "Bonjour"; echo($player_id.new_year2); 4.2.6.4 Méthodes Console En plus du support de la création de fonctions, TorqueScript vous permet de créer des méthodes n'ayant aucune contrepartie C++ associée : function Classname::method_name(%this, [arg0],...,[argn]) { 101 / 223 Documentation de Torque V1.3.x commandes; [return val;] }; La syntaxe se décompose comme suit : function – est un mot-clef indiquant à TorqueScript que nous définissons une nouvelle fonction. Classname:: – est le type de classe avec laquelle, cette focntion est supposée fonctionner. func_name – est le nom de la fonction que nous créons. %this – est une variable qui contiendra l'identifiant de l'objet appelant. ... – est un nombre d'arguments additionnels • • • • • Au minimum, les méthodes Console nécessitent que vous passiez un identifiant d'objet. Vous verrez souvent que le premier argument est appelé %this. Ceci est conseiller, mais vous pouvez le nommer comme vous le voulez. Comme avec les fonctions Console, n'importe quel nombre d'arguments supplémentaires peut être spécifié, séparés par des virgules. En outre, une méthode console peut retourner une valeur optionnelle. Voici quelques exemples : function Goober::hi(%this) { echo("Bonjour Goober ", %this); } En supposant que notre joueur a l'identifiant 1000, si nous tapons : 1000.hi(); nous obtenons, <input> (0): Unknown command hi. Object (1000) Player->ShapeBase->GameBase ->SceneObject->NetObject->SimObject Ce qui est arrivé, est que Torque a recherché la hiérarchie complète de Player et de ses classes-parentes, cherchant une fonction appelée hi() définie dans le contexte d'une de ces classes. N'en trouvant pas, il affiche le message précédent. Pour montrer que Torque cherche la hiérarchie des classes de Player, essayez ceci : function NetObject::hi(%this) { echo("Bonjour NetObject ", %this); } saisissez, 1000.hi(); nous obtenons, Bonjour NetObject 1000 Ensuite, si nous définissons : function Player::hi(%this) { echo("Bonjour Player ", %this); Parent::hi(%this%) } 102 / 223 Documentation de Torque V1.3.x nous pouvons saisir, 1000.hi(); et obtenons, Bonjour Player 1000 Bonjour NetObject 1000 Que s'est-il passé ? Torque a d'abord trouvé Player::hi(), mais nous avons également voulu exécuter la définition précédente de hi(). Pour faire cela, nous avons utilisé le mot-clef 'Parent::'. Bien sûr, ne trouvant pas d'instance de ShapeBase, qui est le parent initial de Player, Torque a alors cherché la chaîne jusqu'à ce qui arrive sur la version de NetObject. Pour finir, nous pouvons forcer Torque d'appeler une instance spécifique ainsi : NetObject::hi(1000); qui nous donne : Bonjour NetObject 1000 et ShapeBase::hi(1000); qui donne aussi : Bonjour NetObject 1000 puisqu'il n'y a pas d'instance ShapeBase de hi() définie. Note : Définir des méthodes avec le même nom que les méthodes Console précédentes surchargent les définitions précédentes définitivement, à moins que la redéfinition ne soit dans un package. 4.2.7 Les packages Les packages fournissent la fonction de polymorphisme dynamique dans TorqueScript. En bref, une fonction définie dans un package surchargera la définition antérieure d'une fonction de même nom lorsque le package est activé. Les packages ont la syntaxe suivante : package nom_package() { function function_definition0() { [commandes;] } ... function function_definitionN() { [commandes;] } }; Choses à savoir : • • • La même fonction peut être définie dans de multiples packages. Seules les fonctions peuvent être en packages. Les datablocks ne peuvent pas être en packages. 103 / 223 Documentation de Torque V1.3.x Les packages peuvent être activés, ActivatePackage(package_name); et désactivés : DesactivatePackage(package_name); La manière la plus facile pour comprendre est avec un exemple. L'exemple ci-dessous est le plus détaillé que nous avons rencontré dans ce guide, mais ne vous inquiétez pas. Il prendra tout son sens quand il le faudra. Copier le code suivant dans un simple fichier texte. Vous pouvez utiliser votre éditeur favori (GarageGames recommande Jedit). Sauvegardez le code dans un nouveau fichier appelé « package_test.cs » et placez-le dans le répertoire « test_scripts » du répertoire exemple précédemment créé. // // Définir une fonction initiale : demo() // function demo() { echo("Definition de demo 0"); } // // Maintenant, définition de trois packages, chacun implémentant // une nouvelle instance de : demo() // package DemoPackage1 { function demo() { echo("Defintion de demo 1"); } }; package DemoPackage2 { function demo() { echo("Defintion de demo 2"); } }; package DemoPackage3 { function demo() { echo("Definition de demo 3"); echo("La definition anterieure de demo etait =>"); Parent::demo(); } }; // // Finalement, définition de quelques fonctions de test // function test_packages(%test_num) { 104 / 223 Documentation de Torque V1.3.x switch(%test_num) { // Utilisation Standard case 0: echo("----------------------------------------"); echo("Une fonction packagee surcharge une definition"); echo("anterieure de la fonction, mais permet a la"); echo("nouvelle definition d'etre \'dechargee\' de"); echo("la pile."); echo("----------------------------------------"); demo(); ActivatePackage(DemoPackage1); demo(); ActivatePackage(DemoPackage2); demo(); DeactivatePackage(DemoPackage2); demo(); DeactivatePackage(DemoPackage1); demo(); // Parents case 1: echo("----------------------------------------"); echo("Le Parent pour une fonction packagee est"); echo("toujours la fonction precedemment activee"); echo("de la fonction packagee."); echo("----------------------------------------"); demo(); ActivatePackage(DemoPackage1); demo(); ActivatePackage(DemoPackage3); demo(); DeactivatePackage(DemoPackage3); DeactivatePackage(DemoPackage1); echo("----------------------------------------"); demo(); ActivatePackage(DemoPackage1); demo(); ActivatePackage(DemoPackage2); demo(); ActivatePackage(DemoPackage3); demo(); DeactivatePackage(DemoPackage3); DeactivatePackage(DemoPackage2); DeactivatePackage(DemoPackage1); // Empilage des singularités case 2: echo("----------------------------------------"); echo("La desactivation d'un package \'intermediaire\'"); echo("desactivera tous les packages \'empiles\' apres"); echo("lui."); echo("----------------------------------------"); demo(); ActivatePackage(DemoPackage1); demo(); ActivatePackage(DemoPackage2); demo(); DeactivatePackage(DemoPackage1); demo(); 105 / 223 Documentation de Torque V1.3.x } } Une fois que vous avez fait cela, charger le script que vous venez juste de créer en ouvrant la console TGE et en tapant : exec("test_scripts/package_test.cs"); Maintenant, le script a été chargé. Torque est ainsi informé de tout le code du fichier. En tant que tels, nous pouvons commencer à utiliser les fonctions que nous avons définies ci-dessus. La manière standard pour utiliser un package est de définir une fonction préalablement définie dans le package, l'activer si nécessaire, et ensuite la désactiver pour revenir à l'état par défaut de la fonction. Pour voir cette action, tapez : test_packages(0); TorqueScript fournit un mot-clef puissant, 'Parent::'. En l'utilisant dans une fonction packagée, nous pouvons exécuter la fonction qui est en cours de surcharge. Pour voir cette action, tapez : test_packages(1); Il est important de comprendre que les packages sont, essentiellement, empilés les uns sur les autres. Ainsi, si vous désactivez un package qui était activé avant un autre package, vous désactivez en effet automatiquement tous les packages qui ont été activés après lui. Pour voir cette action, tapez : test_packages(2); Choses à savoir : • Les packages peuvent définir de nouvelles fonctions. Souvenez-vous, lorsque vous désactivez un package, ces fonctions sont supprimées de l'espace de nommage. • Le mot-clef Parent:: n'est pas récursif, c'est-à-dire Parent::Parent::fun() est illégal. • De nouveau la désactivation de packages activés antérieurement à d'autres packages plus récemment activés, désactive tous les packages activés après. 4.2.8 Les espaces de nommage (namespace) Comme mentionnés précédemment , les espaces de nommage sont fournis dans TorqueScript. Leur méthode de fonctionnement est tout à fait simple. Premièrement, tous les objets appartiennent à un espace de nommage. L'espace de nommage auquel ils appartiennent a par défaut le même nom que la classe. // Espace de nommage de la classe Player Player:: De nouveau comme précédemment mentionné, ces espaces de nommage fournissent une séparation des fonctionnalités, de telle manière qu'on peut avoir des fonctions avec le même nom, mais appartenant à des espaces de nommage séparés. Pour utiliser une de ces fonctions, vous devez soit choisir manuellement l'espace de nommage approprié ou, dans certains cas, ceci est fait automatiquement pour vous. Il est important de comprendre que le « :: » n'est d'aucune manière magique. En fait, vous pouvez créer des fonctions avec « :: » dans leur nom. Cela ne signifie pas qu'elles appartiennent à un espace de nommage. Si l'expression préfixant le « :: » n'est pas une classe ou un espace de nommage valide, en effet tout ce que vous aurez fait, est de créer un nom unique. // Ce n'est pas réellement un espace de nommage function Ver1::doIt() { ... }; function Ver3::doIt() { ... }; 106 / 223 Documentation de Torque V1.3.x 4.2.9 Les datablocks (blocs de données) De toutes les fonctionnalités de TorqueScript, les datablocks sont probablement les plus déroutantes. Pour rendre les choses plus difficiles, ils sont le pivot central dans la création de la plupart des objets, ce qui signifie que vous avez besoin de les comprendre relativement tôt. Je donnerai ici un résumé sur les datablocks, mais puisque vous avez besoin de comprendre quelques sujets supplémentaires avant de réellement plonger dans les datablocks. La définition officielle d'un datablock est : « Les datablocks sont des objets spéciaux qui sont utilisés pour transmettre des données statiques du serveur vers le client » – engine.overview.txt dans le SDK de Torque. Avec les mots de Keanu Reeves lui-même, « Whoaa... ». Ou, peut-être, avec les propres mots, « hein ? ». Cette définition, bien que vraie, ne me donne pas grand-chose. Quelques recherches donnent des définitions supplémentaires : « Un datablock est un objet qui contient un ensemble de caractéristiques qui décrivent un autre type d'objet » – Joel Baxter. C'est mieux, mais c'est encore un peu flou pour moi sur le et l'utilisation des datablocks. « Un datablock est un objet qui peut être déclaré soit en code C++, ou en code de script... Chaque datablock peut alors être utilisé comme un « modèle » pour créer des objets... » – Liquid Creations, tutoriel de script 2 OK, maintenant c'est bon. Les datablocks sont des modèles et nous les utilisons pour créer de nouveaux objets avec les attributs spécifiés par le modèle. Bon. Mais, comment faisons-nous ceci ? Pour la réponse à cette question, vous devrez attendre. Premièrement, nous avons besoin de discuter un peu sur d'autres sujets importants, et alors, nous revisiterons les datablocks et leur donnerons la couverture qu'ils méritent. 4.3 Interface avec le moteur Bien, jusque-là, nous avons parlé du script seul. Maintenant, nous discuterons de l'interface entre la console et le cœur du moteur. 4.3.1 Terminologie Avant de commencer, il est important de définir un ensemble cohérent de termes pour décrire les concepts que nous allons aborder : Table 42 : terminologie de l'interface moteur-console Terme Définition Termes spécifiques - C++ Variable C++ • Une variable C++ n'est associée avec aucune classe. Fonction C++ • Une routine déclarée et définie en C++, qui n'est associée à aucune classe. Membre • • Une variable déclarée et définie dans une classe C++. Peut être accédé seulement en association avec une instance d'un objet. Méthode • • Une routine déclarée et définie dans une classe C++. Peut être accédé seulement en association avec une instance d'un objet. Termes spécifiques - script Variable locale ou globale • • Une variable dans la console les variables globales peuvent être définies en C++ et liées aux variables globales du moteur. Modificateurs de code C++ autorisés : const, static. 107 / 223 Documentation de Torque V1.3.x Terme Définition Fonction • • Une routine dans la console associée avec aucun espace de nommage. Peut être entièrement définie en script ou en C++. Champ • • Une variable associée avec un objet dans la console Lié à un membre. Champ dynamique • • Une variable associée avec un objet dans la console Existe uniquement dans la console. Commande (dépréciée) • Une routine associée avec un espace de nommage particulier dans la console. Liée à une méthode existante Les commandes de console sont obsolètes – elles ne doivent plus être utilisées. Elles ne sont fournies que pour référence. • • Méthode de console • • Une routine associée avec un espace de nommage particulier dans la console. Existe uniquement dans la console. On dit qu'un dessin vaut mieux qu'un long discours. Dons, voici une illustration de la table ci-dessus : Le moteur La console Variable C++ locale Variable locale Variable globale Con::AddVariable() Variable C++ globale Variable globale Fonction C++ Fonction console ConsoleFunction() Fonction console Instance d'objet Con::AddField() Membre Con::AddCommand() Champ Champ dynamique Méthode Commande ConsoleMethod() Méthode console 4.3.2 Matrice des problèmes/solutions d'interface du moteur 108 / 223 Documentation de Torque V1.3.x Avant de sauter dans les détails de l'interface du moteur et de la console, voici la matrice des problèmes et des solutions : Table 43 : matrice des problèmes/solutions de l'interface du moteur Problème Solution Type de solution C++ vers Console Exposer un membre comme champ addField() Fonction addFieldV() Exposer un membre comme champ addNamedField() Macro addNamedFieldV() Exposer/Supprimer une variable C++ globale ou un membre statique comme variable locale Con::addVariable() Exposer une méthode comme commande (obsolète) Con::addCommand() (obsolète) Con::removeVariable() Créer une méthode console à partir du C++ ConsoleMethod() Créer une fonction console à partir du C++ Fonction ConsoleFunction() Fonction Macro Macro 4.3.3 addField() Cette fonction vous permet de lier des membres de classe C++ à des champs d'objets de la console. Les règles d'utilisation de cette fonction sont : • • • Le membre à exposer ne doit pas être dynamique (c'est-à-dire pas un pointeur) Le membre à exposer ne doit pas être statique. La commande addField() doit être incluse dans la méthode initPersistFields(). de classe Void ConsoleObject::addField(const char* in_pFieldname, const U32 in_fieldType, const dsize_t in_fieldOffset, const char* in_pFieldDocs) Void ConsoleObject::addField(const char* in_pFieldname, const U32 in_fieldType, const dsize_t in fieldOffset, const U32 in_elementCount, EnumTable *in_table, const char* in_pFieldDocs) • • • • • • in_pFieldname – chaîne spécifiant le nom de la variable utilisée dans la console. in_fielfType – le type du champ (les types sont spécifiés dans le fichier consoleTypes.h) in_fieldOffset – c'est une valeur numérique calculée en utilisant la macro Offset(). in_elementCount – nombre d'éléments de l'offset. La valeur par défaut est 1, mais si vous référencez un tableau alors cette valeur sera le nombre d'éléments du tableau. in_table – cet argument est utilisé lorsque le type de champ est TypeEnum. Dans ce cas spécial, vous devez définir une EnumTable contenant une carte des valeurs ENUM et des chaînes pour les représenter dans la console. in_pFieldDocs – une courte chaîne décrivant le champ en clair. Ce champ est utilisé par la fonctionnalité automatique de documentation de la console de Torque. Voici un exemple (trouvé dans le fichier guiCrossHairHud.cc) : 109 / 223 Documentation de Torque V1.3.x class GuiCrossHairHud : public GuiBitmapCtrl { ... ColorF mDamageFillColor; // déclaré ici ... }; void GuiCrossHairHud::initPersistFields() { ... addField( "damageFillColor", TypeColorF, Offset( mDamageFillColor, GuiCrossHairHud)); // ajouté dans initPersistFields() ... } Dans ce code, le membre mDamageFillColor a été lié au champ damageFillColor. Si vous souhaitez tester la capacité d'inspecter et modifier ce champ, faites cela : • • • • • • • Exécutez le SDK Lancez n'importe quelle mission Ouvrez l'éditeur GUI (F10) et trouvez GuiCrossHairHud dans l'arbre de l'inspecteur GUI Retenez l'identifiant du contrôle Arrêter l'éditeur GUI (F10) Ouvrez la console (~) Essayez ces commandes (substituez le #### par l'identifiant) : echo(####.damageFillColor); ####.damageFillColor = " 1.0 0.0 0.0 1.0"; echo(####.damageFillColor); Vous pouvez noter que bien que le contenu de la variable ait été modifié (avec le rouge 100 % opaque), le réticule reste vert. Car vous modifiez la copie serveur de la variable, mais pas la copie client. La relation entre les client et serveurs peut dérouter. Nous n'avons pas la place ici pour détailler, mais pour une meilleure compréhension, reportez-vous à la documentation sur la partie réseau de Torque. Dans un souci de clarté, voici quelques exemples démontrant l'utilisation de cette fonction : //// Ajout d'une variable simple // la variable que nous voulons ajouter bool bTorqueRocks; // ajout de la variable addField( "TorqueRocks", TypeBool, Offset(bTorqueRocks,EGTClass)); //// Ajout d'un tableau // la variable que nous voulons ajouter S32 arynEGTChapters[28]; // ajout de la variable addField( "TorqueRocks", TypeS32, Offset(arynEGTChapters,EGTClass),28); //// Ajout d'un ENUM // la variable que nous voulons ajouter StateData::LoadedState stateLoaded[MaxStates]; // la EnumTable static EnumTable::Enums enumLoadedStates[] = { { ShapeBaseImageData::StateData::IgnoreLoaded, "Ignore" }, { ShapeBaseImageData::StateData::Loaded, "Charge" }, { ShapeBaseImageData::StateData::NotLoaded, "Vide" }, 110 / 223 Documentation de Torque V1.3.x }; static EnumTable EnumLoadedState(3, &enumLoadedStates[0]); // ajout de la variable addField("stateLoadedFlag", TypeEnum, Offset(stateLoaded, ShapeBaseImageData), MaxStates, &EnumLoadedState); Après avoir couvert la version la plus utilisée des fonctions addFields(), regardons rapidement l'utilisation et la syntaxe des autres variétés. 4.3.4 addFieldV() C'est une version spécialisée de la fonction addField(). Elle ne gère pas les tableaux ou les ENUM, mais elle dispose d'une fonction Validator. Regardons à la syntaxe et expliquons les fonctions Validator. Void ConsoleObject::addFieldV(const char* in_pFieldname, const U32 in_fieldType, const dsize_t in_fieldOffset, TypeValidator *v) • • • • in_pFieldname – chaîne spécifiant le nom de la variable utilisée dans la console. in_fielfType – le type du champ (les types sont spécifiés dans le fichier consoleTypes.h) in_fieldOffset – c'est une valeur numérique calculée en utilisant la macro Offset(). v – ceci est un pointeur vers un une classe TypeValidator où il y a plusieurs types dérivés à choisir. Vous pouvez trouver les définitions de Validator prédéfinies dans le fichier typeValidators.h, et il est possible de créer vos propres classes Validator. 4.3.5 Type de classes Validator Les classes de type Validator sont utilisées pour limiter les valeurs qu'un champ peut recevoir. Si des valeurs illégales sont assignées à un champ validé, la fonction Validator affichera une erreur dans la console et positionne le champ à une valeur valide. Les deux types de classe Validator les plus utilisés sont FRangeValidator et IRangeValidator. Comme vous pouvez l'imaginer, le premier s'assure que les valeurs entrées par un utilisateur dans un champ 'à valider' sont dans une gamme de valeurs à virgules flottantes. Le suivant est utilisé pour les entiers. //// tiré du fichier projectile.cc au environ de la ligne 126 // le rayon d'éclairage est limité entre 1.0 à 20.0, inclus. addNameFieldV(lightRadius, TypeF32, ProjectileData, new FrangeValidator(1, 20)); 4.3.6 addNamedField() et addNamedFieldV() Ces deux variantes de addField() sont actuellement des macros qui ne font rien de plus que de donner au champ de la console le même nom que le membre de classe étant accédé. #define addNamedField(fieldName,type,className) type, Offset(fieldName,className)) \ addField(#fieldName, #define addNamedFieldV(fieldName,type,className, validator) \ addFieldV(#fieldName, type, Offset(fieldName,className), validator) 4.3.7 Macro Offset() J'ai passé jusqu'à présent sur la macro Offset() afin de discuter en premier sur l'utilisation de addField() et de ses différentes versions. La macro Offset() est chouette, car elle calcule la position d'une variable dans une instance d'une classe. Ou plus exactement, la macro Offset() calcule en octets, à partir du début de la classe en mémoire, la position d'une variable. Voici la syntaxe : Offset(VariableName, ClassName) 111 / 223 Documentation de Torque V1.3.x • • VariableName – c'est le nom (C++) du membre de la classe que nous voulons exposer ClassName – c'est le nom de la classe où le membre réside 4.3.8 removeField() Cette fonction vous permet de délier une paire membre-champ précédemment liée. En fait, ceci supprime entièrement le champ de la console. Aussi simple que cela. Pourquoi le faire ? Considérez le cas où vous dérivez d'un objet qui fait un appel addField() pour un membre que vous décidez qu'il ne serait pas accessible (comme la position pour les données du terrain). bool ConsoleObject::removeField(const char* in_pFieldname) • in_pFieldname – chaîne spécifiant le champ à supprimer // 1. TerrainBlock est hériré de SceneObjet. // 2. SceneObjet lie le membre mObjToWorld avec la position. // 3. TerrainBlock annule cela (dans terrData.cc) removeField("position"); 4.3.9 Con::addVariable Cette fonction vous permet d'exposer une variable globale C++ ou un membre statique en tant que variable globale dans la caméra (voir camera.cc). Con::addVariable(const char *name, S32 t, void *dp); • • • name – chaîne spécifiant le nom d'une variable globale (dans la console). t – le type de variable (les types sont spécifiés dans consoleTypes.h). dp – un pointeur vers la variable globale C++, ou le membre statique. Le code précédent expose la variable globale C++ mMovementSpeed dans la console en tant que variable nommée Camera::movementSpeed. Note : ceci contrôle la vitesse de la caméra à survol libre durant l'édition. Maintenant, vous connaissez une autre manière pour la régler. 4.3.10 Con::removeVariable (obsolète) Cette fonction vous permet de supprimer une variable globale de la console ayant été précédemment ajoutée avec une des variantes de la fonction addVariable(). bool removeVariable(const char *name) • name – chaîne spécifiant le nom d'une variable globale (dans la console). Lors de la recherche, je n'ai pas trouvé une seule instance dans laquelle cette fonction est utilisée. 4.3.11 Con::addCommand (obsolète) Cette fonction vous permet d'exposer une méthode en tant que commande. Cependant, elle est obsolète – vous n'êtes pas encouragé à l'utiliser. À la place, vous devrez créer une méthode en C++ (si vous devez l'utiliser dans le moteur ou elle doit être rapide), et ensuite appelez cette méthode dans une ConsoleMethod. 4.3.12 ConsoleMethod Ceci est une macro qui vous permet de créer une nouvelle méthode de console du C++. L'utilisation de ConsoleMethod() n'est pas très étendue dans le moteur, car elle a été choisie en remplacement de l'appel beaucoup plus lourd de addCommand(). La variante statique de ConsoleMethods est pour les méthodes que vous souhaitez appeler de manière statique. Par exemple, GameConnection::getServerConnection(). 112 / 223 Documentation de Torque V1.3.x ConsoleMethod(className,scriptname,returnType,minArgs,maxArgs,usage) ConsoleStaticMethod (className,scriptname,returnType,minArgs,maxArgs,usage) • • • • • • className – le nom de la classe d'où est la méthode. scriptname – le nom de la méthode qui sera donné dans la console (c'est-à-dire utilisé par TorqueScript returnType – le type de retour de la méthode. minargs – le nombre minimum d'arguments pouvant être passés à cette méthode. Note : le minimum est 2, car le nom de la méthode de la console est automatiquement passé comme premier argument et l'identifiant est passé en tant que second. maxargs – le nombre maximum d'arguments pouvant être passés à cette méthode. Note : si vous mettez 0 dans ce champ, cela signifie que n'importe quel nombre d'arguments peut être passés à la méthode. usage – une chaîne qui sera affichée en tant qu'aide si quelqu'un, plus tard, tente d'utiliser cette méthode avec un nombre incorrect d'arguments. Cet usage est aussi lorsque vous utilisez la commande obj.dump(). // À partir de SimBase.cc ConsoleMethod(SimObject, getId, S32, 2, 2, "obj.getId()") { argc; argv; return object->getId(); } Dans la fonction précédente, nous avons (enfin, les vrais auteurs du moteur...) écrit un utilitaire simple pour retourner l'ID unique de l'objet courant (son identifiant). D'autres détails : • • • • • • • Elle peut être appelée par tous les objets qui sont des SimObject ou des enfants de SimObject. Le nom de la fonction dans TorqueScript sera getId ou plus précisément SimObject::getId. getId prend deux arguments, le nom ConsoleMethod et l'identifiant de l'objet (qui est la même chose que ce que nous voulons qu'il soit retourné). La ConsoleMethod est prévue pour retourner une valeur signée sur 32 bits. La ConsoleMethod prendra un minimum et un maximum de deux arguments. Le message usage est : « obj.getId() » En interne, • nous ne faisons rien avec les variables argc et argv standards. • Nous appelons une méthode nommée getId() pour retourner une valeur signée sur 32 bits. 4.3.13 ConsoleFunction Ceci est une macro qui nous permet de créer une nouvelle fonction de console à partir du C++. Exemple : ShapeBase.cc. ConsoleFunction(name,returnType,minArgs,maxArgs,usage) • • • • • name – ceci est le nom de la fonction comme elle sera utilisée dans la console. returnType – est le type retourné par la fonction. minargs – nombre minimum d'arguments pouvant être passés à la fonction. Note : 1 est le minimum, car le nom de la fonction est automatiquement passé comme premier argument. maxargs – nombre maximum d'arguments pouvant être passés à la fonction. Note : si vous mettez 0 dans ce champ, cela signifie que n'importe quel nombre d'arguments peut être passés à la fonction. usage – est une chaîne qui sera affichée en tant qu'aide si quelqu'un, plus tard, tente d'utiliser cette fonction avec un nombre incorrect d'arguments. 113 / 223 Documentation de Torque V1.3.x // À partir de main.cc ConsoleFunction( getSimTime, S32, 1, 1, "getSimTime() - Temps depuis le début du jeu.") { return Sim::getCurrentTime(); } Premièrement, j'ai corrigé la déclaration de ConsoleFunction ci-dessus pour cet exemple. Dans le moteur, le paramètre usage était utilisé à la place pour donner des informations sur le but de la fonction. Réellement, nous voudrions qu'elle nous dise quoi faire si nous avions commis une erreur dans la liste des arguments. Il est assez clair que ceci crée une fonction dans la console nommée getSimTime, qui retourne une valeur signée sur 32 bits, et prend 1 argument. Intéressant, à l'intérieur, nous appelons la méthode statique Sim::getCurrentTime(). Rappelez-vous, les fonctions de la console peuvent appeler en interne n'importe quelle fonction dans le contexte de la déclaration de la macro ou n'importe quelle méthode statique. 4.3.14 Fonctions supplémentaires d'interface du moteur En plus des fonctions majeures dont nous avons parlé jusqu'ici, il y a quelques autres fonctions importantes, bien que moins utilisées, que vous devriez connaître. Je les aborderai brièvement, et compte sur vous pour examiner les codes source des exemples. Note : j'utiliserai quelques-unes d'entre elles dans les tutoriels qui apparaîtront dans ce guide. 4.3.14.1 Con::getLocalVariable() Cette fonction vous permet d'obtenir le contenu d'une variable locale de la console à partir du moteur. Note : la valeur est retournée comme chaîne de caractères. const char *Con::getLocalVariable(const char* name); • name – ceci est le nom de la variable locale de la console. 4.3.14.2 Con::setLocalVariable() Cette fonction vous permet d'initialiser une variable locale de la console à partir du moteur. Note : toutes les valeurs sont passées comme chaîne de caractères. La console les convertit automatiquement si nécessaire. Con::setLocalVariable(const char *name, const char *value); • • name – ceci est le nom de la variable locale de la console. value – ceci est la nouvelle valeur à mettre dans la variable de la console 4.3.14.3 Fonctions d'affichage de la console • • • Con::printf() Con::warnf() Con::errorf() Ces fonctions fournissent la possibilité d'afficher différents niveaux d'information dans la console (et dans le journal (log) si la journalisation est active). Con::printf(const char *_format, ...); • • _format – une chaîne de formatage au standard printf du C. ... – n'importe quel nombre d'arguments associés avec le contenu de la chaîne de formatage. Con::warnf(ConsoleLogEntry::Type type, const char *_format, ...); • _type – un indicateur de catégorie, où la catégorie peut être : • General • Assert 114 / 223 Documentation de Torque V1.3.x Script GUI Network _format – une chaîne de formatage au standard printf du C. ... – n'importe quel nombre d'arguments associés avec le contenu de la chaîne de formatage. • • • • • 4.4 Retour sur les datablocks, les objets et les espaces de nommage OK, nous avons déjà abordé ces sujets, mais seulement en les effleurant. Maintenant, il est temps de baisser la barre, attachez vos ceintures, et ne vous penchez pas à l'extérieur à tout moment... 4.4.1 La connexion aux objets datablocks Le débutant dans Torque sera un brin perturbé, jouant avec les exemples fournis avec Torque. Éventuellement surgit la question, « Pourquoi y a-t-il des objets faits avec des datablocks et d'autres non ? » Bien, la réponse est relativement simple. Les objets placés dans le monde du jeu tomberont dans une des trois grandes catégories : 1. L'objet n'a pas beaucoup de données associées et/ou a peu de paramètres. 2. L'objet a un tas de paramètres, mais ces paramètres sont susceptibles d'être uniques, ou peuvent être autorisés à être uniques, entre les instances de l'objet. 3. L'objet a un tas de données et de paramètres, mais ces données/paramètres peuvent être partagés entre les instances. Les deux premières catégories correspondent aux classes d'objets qui ne sont pas créées à partir de datablock, et n'en ont pas besoin. Réciproquement, la troisième catégorie correspond à la classe d'objets pouvant bénéficier de l'utilisation de datablocks. Pourquoi ? Comment ? Bien, jusqu'à ce point, je n'ai pas précisé un petit point sur les datablocks. À la différence des objets normaux, vous ne pouvez avoir qu'une seule instance de n'importe quel datablock. En outre, les objets qui sont créés à partir de datablocks partagent tous la même instance de ce datablock. Je peux sentir que certaines personnes secoueront leur tête à ce point, jetons donc un coup d'œil à la table suivante, qui devrait clarifier les relations : Table 44 : Objet créé sans datablock • • • Objet créé avec un datablock Créé directement à partir d'une classe C++ Contient des champs Peut contenir des champs dynamiques new PhysicalZone() { position = "371.851 322.83 218"; rotation = "1 0 0 0"; scale = "1 1 1"; velocityMod = "1"; gravityMod = "1"; appliedForce = "0 0 0"; polyhedron = "0 0 0 1 0 0 0 -1 0 0 0 1"; }; • • • • Créé directement à partir d'une classe C++ Contient des champs Peut contenir des champs dynamiques Requiert un champ datablock supplémentaire, qui est rempli à partir d'un datablock précédemment défini datablock StaticShapeData(SimpleTarget0) { category = "Targets"; shapeFile = "~/data/.../simpletarget.dts"; }; new StaticShape() { position = "360.17 325.775 219.906"; rotation = "1 0 0 0"; scale = "1 1 1"; dataBlock = "SimpleTarget0"; }; 4.4.1.1 Création d'objets sans datablock J'ai précédemment fourni la syntaxe pour la création d'objets, mais allons-y et créons quelques variations 115 / 223 Documentation de Torque V1.3.x d'objets sans datablock pour clarifier l'utilisation de cette syntaxe. Nous utiliserons PhysicalZones dans tous les exemples : new PhysicalZone() { }; L'exemple précédent crée une pzone, mais ne spécifie pas le nom, et ne donne aucun paramètre, donc il prendra la valeur par défaut fournie par le contructor de la classe C++. new PhysicalZone(SpeedupZone) { position = "0 0 0"; velocityMod = "2"; }; L'exemple précédent créera une pzone nommée 'SpeedupZone' et positionnée en <0,0,0>. Cette pzone particulière multipliera la rapidité du joueur par deux lorsque le jouer entre dans la zone. new PhysicalZone(SpeedupZone2 : SpeedupZone) { position = "10 10 10"; }; L'exemple précédent créera une pzone nommée 'SpeedupZone2' et positionnée en <10,10,10>. Hormis la position, qui a été redéfinie, elle héritera de tous les paramètres de notre exemple précédent, 'SpeedupZone'. new PhysicalZone(FloatySpeedupZone : SpeedupZone) { position = "20 20 20"; gravityMod = "-2"; LastPlayerID = 0; }; L'exemple précédent créera une pzone nommée 'FloatySpeedupZone' et positionnée en <20,20,20>. En plus de surcharger position, elle surcharge gravityMod, donnant au bloc une gravité de -2. Comme avec 'SpeedupZone2', cet objet hérite du reste des valeurs des paramètres qui n'ont pas été surchargés de 'SpeedupZone'. Pour finir, il ajoute un champ dynamique nommé 'LastPlayerID' et lui donne une valeur nulle. Ainsi, que dire de ces arguments additionnels ? Vous savez : %var = new ObjectType(Name : CopySource, arg0, ..., argn) {}; Bon, cette caractéristique est en dehors du domaine de ce guide. Si vous comprenez une fonction particulière de ce guide, vous ne lisez probablement pas ce guide pour apprendre. 4.4.1.2 Création d'objets avec datablock Bien, après avoir vu quelques exemples de création d'objets sans datablock, nous pourrions juste couvrir le cas du datablock, mais je vous montrerai les deux, juste pour renforcer l'utilisation de l'héritage. new StaticShape(TestTarget) { position = "0 0 0"; rotation = "1 0 0 0"; scale = "1 1 1"; dataBlock = "SimpleTarget0"; }; 116 / 223 Documentation de Torque V1.3.x L'exemple précédent crée une StaticShape nommée 'TestTarget'. Elle définit la position, la rotation, et l'échelle. En plus, elle dit au moteur d'utiliser le datablock 'SimpleTarget0' pour initialiser ce datablock de l'objet. Ultérieurement, cet objet sera toujours associé avec le datablock 'SimpleTarget0'. new StaticShape(TestTarget2: TestTarget) { position = "0 10 0"; }; L'exemple précédent crée une autre StaticShape. Celle-ci est nommée 'TestTarget2'. Elle hérite de tous les paramètres de TestTarget et surcharge position. La chose importante à comprendre est qu'elle partage le datablock 'SimpleTarget' avec l'autre instance de StaticShape, 'TestTarget'. C'est-à-dire que nous avons deux instances de StaticShape qui partagent le datablock 'SimpleTarget0'. Avant d'aller sur les datablocks, regardons la relation entre la classe et le datablock. Ces classes de datablocks ont habituellement un nom intuitif. Par exemple : Table 45 : Classe utilisant un datablock Nom du datablock StaticShape StaticShapeData Item ItemData Vehicle VehicleData ... et ainsi de suite. 4.4.1.3 Déclaration de datablocks Jusqu'à maintenant, nous avons clarifié la connexion entre les objets et les datablocks. Nous avons indiqué que les datablocks sont des objets dans le monde du jeu. Nous avons démontré que seule une instance de n'importe quel datablock est créée et partagé avec n'importe quel nombre d'objets utilisant le datablock. Et, pour finir, nous avons montré qu'il y a une relation 1-à-1 entre les classes utilisant les datablocks et les classes de datablock dans le moteur. La seule chose restante à discuter pour nous est la déclaration des datablocks. Nous déclarons les datablocks de manière similaire à la création des objets. Syntaxe de déclaration d'un datablock : // In TorqueScript datablock DataBlockType(Name [: CopySource]) { category = "CategoryName"; [datablock_field0 = Value0;] ... [datablock_fieldM = ValueM;] [dynamic_field0 = Value0;] ... [dynamic_fieldN = ValueN;] }; Comme vous pouvez le voir, ceci est presque identique à la syntaxe utilisée pour créer un objet console. • • datablock – un mot-clef indiquant au moteur que ceci est un objet datablock. DatablockType – n'importe quelle classe de datablock déclarée dans le moteur a été dérivée de GameBaseData ou d'une sous-classe de GameBaseData. 117 / 223 Documentation de Torque V1.3.x • • • • • Name (optionnel) – n'importe quelle expression s'évaluant en chaîne, qui sera utilisée comme nom du datablock. CopySource (optionnel) – une définition précédente de datablock de laquelle les valeurs seront héritées. category – un mot-clef qui indique au moteur où placer cet objet dans l'arbre de création de l'éditeur de monde. Si la 'CategoryName' n'existe pas dans l'arbre, il sera créé. dynamic_fieldM – vous pouvez initialiser n'importe lequel ou tous les champs existants dans le datablock. dynamic_fieldN – comme avec les objets, vous pouvez ajouter des champs au datablock qui ne sont pas définis dans la version C++. Cependant, à la différence des objets, une fois définies, ces valeurs sont statiques. Note : il y a une méthode pour modifier quand même les valeurs des datablocks, mais cela hors propos dans ce chapitre. Maintenant, quelques exemples : datablock StaticShapeData(MyTargets) { category = "Targets"; shapeFile = "~/data/shapes/targets/simpletarget0.dts"; }; L'exemple précédent déclare un datablock de type StaticShapeData nommé 'MyTargets'. En plus, nous avons spécifié que ce StaticShape devrait être situé dans le répertoire Targets dans l'arbre de création de l'éditeur de monde. Pour finir, il utilise le fichier de forme « ~/data/shapes/targets/simpletarget0.dts ». datablock StaticShapeData(SimpleTarget0 : MyTargets) { StartHidden = 1; }; L'exemple précédent déclare un datablock de type StaticShapeData nommé 'SimpleTarget0' qui hérite de toutes les données de MyTargets. En plus, la déclaration ajoute une nouvelle variable nommée 'StartHidden' initialisée à 1. Voilà, c'est vraiment simple. Maintenant, parlons des espaces de nommage... 4.4.2 Les espaces de nommage me donnent mal à la tête ! Pourquoi ce titre ? Bien, pour être honnête, lorsque j'ai commencé à écrire ce guide je pensais, « Ah, ouais... j'ai cette chose, l'espace de nommage... pas de problème ». Ensuite, la réalité m'a rejoint. J'ai commencé par la création de cas-tests pour un projet d'un jour, et j'ai trouvé que je m'étais emmêlé les pinceaux quelque part. Après quelques jours et l'aide de Josh Williams, ma tête tenait toujours. Pour chaque objet dans Torque, il y a un espace de nommage. En plus, les espaces de nommage sont chaînés. Cela signifie que, lorsque le moteur commence à chercher quelque chose dans l'espace de nommage, il part du point d'entrée associé avec l'objet courant et remonte au travers de tous les espaces de nommage parents jusqu'à ce qu'il trouve ce qu'il cherche, ou bien jusqu'à ce qu'il échoue. « Oui, oui », vous dites, « nous couvrirons ceci, mais comment utilisons-nous cette fonctionnalité ? » Pour répondre à cette question, nous regarderons quelques exemples en commençant par le plus simple. 4.4.2.1 Hiérarchies d'espace de nommage d'objet Lorsque nous souhaitons créer une nouvelle fonction pour l'espace de nommage d'un objet, nous faisons quelque chose du genre : function GameBase::doIt(%this) { echo ("Appel de StaticShape::doIt() ==> sur l'objet" SPC %this); }; 118 / 223 Documentation de Torque V1.3.x La fonction 'doIt' est déclarée dans l'espace de nommage 'GameBase'. Cela signifie, que nous pouvons appeler cette fonction à partir de n'importe quel objet créé à partir de la classe GameBase ou de ses enfants. Par exemple : %myTarget = new StaticShape(CoolTarget) { position = "0 0 0"; dataBlock = "SimpleTarget1"; }; %myTarget.doIt(); En supposant que l'identifiant de %myTarget est, disons... 100, l'appel précédent devrait produire l'affichage dans la console : Appel de StaticShape::doIt() ==> sur l'objet 100 Si vous êtes observateur, vous aurez remarqué deux choses : 1. Lorsque nous appelons doIt(), nous le faisons sans passer explicitement un argument, mais lorsque le message console est affiché, il a en fait obtenu un argument avec la valeur 100. 2. L'argument pris par doIt() est %this. Concernant le premier point, puisque nous utilisons l'identifiant pour appeler la fonction (%myTarget.doIt()), l'identifiant (ID) de cet objet est passé implicitement à la fonction. Cela dit, tous les appels suivants produiront le même résultat : %myTarget.doIt(); StaticShape::doIt(%myTarget); CoolTarget.doIt(); "CoolTarget".doIt(); 100.doIt() "100".doIt() StaticShape::doIt(100); Comme vous pouvez le voir, il y a différentes manières pour appeler la même fonction, toutes sont utiles dans différents scénarios. TorqueScript n'est-il pas grand ? Veuillez noter que dans les cas où nous utilisons le nom de l'objet, le nom sera passé comme l'ID. Torque automatiquement effectuera la correspondance pour les noms, ainsi dans la plupart des cas, les noms peuvent être interchangés avec les ID, tant que les noms sont uniques. Jusque-là, tout va bien, nous avons discuté des utilisations de base des espaces de nommage. Maintenant, parlons des espaces de nommage de datablock. 4.4.2.2 Espaces de nommage de datablock simple Comme indiqué précédemment, les datablocks ne sont rien d'autre que des objets eux-mêmes. Ils existent dans la console à côté des objets réguliers et ils ont aussi leurs propres espaces de nommage. Par exemple, si nous souhaitons créer une nouvelle fonction pour l'espace de nommage ItemData, nous pouvons effectuer quelque chose du type : function ItemData::GetFields(%ItemDbID) { echo ("Appel de ItemData::GetFields () ==> de l'objet" SPC %ItemDbID); echo (" catetory =>" SPC %ItemDbID.category); echo (" shapeFile =>" SPC %ItemDbID.shapeFile); echo (" mass =>" SPC %ItemDbID.mass); echo (" elasticity =>" SPC %ItemDbID.elasticity); echo (" friction =>" SPC %ItemDbID.friction); echo (" pickUpName =>" SPC %ItemDbID.pickUpName); 119 / 223 Documentation de Torque V1.3.x echo (" maxInventory =>" SPC %ItemDbID.maxInventory); } La fonction 'GetFields' est déclarée dans l'espace de nommage 'ItemData'. Considérant que CrossbowAmmo est une instance de ItemData : // issu de crossbow.cs (édité) datablock ItemData(CrossbowAmmo) { category = "Ammo"; shapeFile = "~/data/shapes/crossbow/ammo.dts"; mass = 1; elasticity = 0.2; friction = 0.6; pickUpName = "crossbow bolts"; maxInventory = 20; }; Nous pourrions appeler ainsi notre nouvelle fonction et obtenir : ==>CrossbowAmmo.GetFields(); Appel de ItemData::GetFields () ==> de l'objet CrossbowAmmo catetory => Ammo shapeFile => egt/data/shapes/crossbow/ammo.dts mass => 1 elasticity => 0.199413 friction => 0.599218 pickUpName => crossbow bolts maxInventory => 20 Maintenant, cela peut paraître complètement trivial, mais il est important de comprendre que la majorité des méthodes intéressantes qui sont appelées par le moteur ayant une réponse à une action de l'utilisateur, comme onCollision(), onAdd(), etc., ne sont pas appelées sur des instances d'objets. Elles sont appelées sur les datablocks des instances des objets utilisant les datablocks. Ceci est crucial, car nous pouvons faire certaines choses spéciales avec les datablocks et leurs espaces de nommage. 4.4.2.3 Insertion d'espaces de nommage de datablock (className) Les datablocks fournissent un lien afin de manipuler les séquences d'appel des espaces de nommage. Ce lien est le champ className. Vous le verrez utilisé dans crossbow.cs pour le datablock CrossbowAmmo. Il fonctionne ainsi : datablock ItemData(CrossbowAmmo) { ... className = "Ammo"; ... }; Ce qu'il fait, c'est l'ajout d'un nouvel espace de nommage entre CrossbowAmmo et ItemData, de sorte que la séquence d'appel de l'espace de nommage ressemble à ceci : CrossbowAmmo -> Ammo -> ItemData -> etc. Si nous définissions ainsi deux fonctions : function Ammo::onPickup(%AmmoDB, %AmmoOBJ, %Picker, %Amount) { echo ("Appel de Ammo::onPickup () ==> de ammo DB" SPC %AmmoDB); %AmmoDB.DoIt(); } 120 / 223 Documentation de Torque V1.3.x function Ammo::DoIt(%AmmoDB) { echo ("Appel de Ammo::DoIt () ==> de ammo DB" SPC %AmmoDB); } Nous pourrions alors nous heurter à un élément ammo et compter voir le message suivant : Appel de Ammo::onPickup () ==> de ammo DB 66 Appel de Ammo::DoIt () ==> de ammo DB 66 Cette puissante fonctionnalité nous permet d'insérer un espace de nommage spécial que nous pouvons utiliser pour plusieurs datablocks différents. En d'autres termes, si nous devions définir ainsi deux éléments de Datablocks : datablock ItemData(FlamingCrossbowAmmo) { ... className = "Ammo"; ... }; datablock ItemData(ExplodingCrossbowAmmo) { ... className = "Ammo"; ... }; Plus tard, dans le code de l'objet dérivé, les trois datablocks différents CrossbowAmmo, FlamingCrossbowAmmo et ExplodingCrossbowAmmo pourront tous utilisés les mêmes fonctions onPickup() et doIt() comme déclarées dans l'espace de nommage Ammo::. Ceci réduit la quantité de code que nous devons écrire. 4.4.2.4 Héritage d'espaces de nommage ? Vous pourriez vous demander parfois, si des hiérarchies d'espace de nommage peuvent être héritées. La réponse est : non. Si nous faisons cela : datablock ItemData(CrossbowAmmo) { ... // no classNameField ... }; datablock ItemData(FlamingCrossbowAmmo : CrossbowAmmo) { ... }; La séquence d'appel des espaces de nommage pour CrossbowAmmo sera : CrossbowAmmoi -> ItemData -> etc., et pour FlamingCrossbowAmmo -> ItemData -> etc. Si nous voulons que FlamingCrossbowAmmo utilise l'espace de nommage de CrossbowAmmo, nous avons à faire ceci : datablock ItemData(CrossbowAmmo) { ... // pas de champ className ... 121 / 223 Documentation de Torque V1.3.x }; datablock ItemData(FlamingCrossbowAmmo) { ... className = "CrossbowAmmo"; ... }; Note : si vous définissez un champ className dans un datablock, les enfants de ce datablock copieront cette valeur dans leur propre champ className à moins qu'il ne soit surchargé dans la définition enfant : datablock ItemData(CrossbowAmmo) { ... className = "Ammo"; ... }; datablock ItemData(FlamingCrossbowAmmo) { ... }; Maintenant, la séquence d'appel d'espaces de nommage pour CrossbowAmmo sera : CrossbowAmmoi -> -> Ammo -> ItemData -> etc., et pour FlamingCrossbowAmmo ça sera : FlamingCrossbowAmmo -> Ammo -> ItemData -> etc. 4.4.2.5 Rappel final (espaces de nommage d'objet vs. datablock) Avant de fermer ce chapitre, je veux prendre un moment pour vous rappeler que lorsque vous créez de nouveaux objets utilisant des datablocks, la majorité des fonctions appelées par le moteur, le sont sur le datablock de l'objet, et non sur l'objet lui-même. J'ai vu maintes fois des questions sur les forums qui ont pour base une confusion sur ce sujet. Ainsi, économisez-vous beaucoup de peine, et conservez cette notion fermement en tête. 4.5 Résumé Ce fut un long chapitre, mais vous l'avez parcouru. Il est douteux que quelqu'un puisse entièrement absorber toutes les informations présentées dans ce chapitre après juste une lecture. Quand vous travaillerez avec Torque et rencontrerez des problèmes, utilisez ce chapitre comme une ressource, et rafraîchissez vos connaissances avec les sections nécessaires. Voici le récapitulatif de ce que nous avons couvert : Premièrement, nous avons parlé de ce que sont les langages de script et pour quoi ils sont utiles. Nous avons discuté des fonctionnalités qu'un bon langage de script devait avoir, et découvert que TorqueScript les a toutes. Avec une analyse introductive, nous sommes entrés dans TorqueScript, étudiant en détail chacune des fonctionnalités du langage. Nous avons parlé des variables de TorqueScript – étudiant le nommage d'une variable et son contexte, et les types de données : numérique, chaîne, booléen, tableau et vecteur. Continuant avec un aperçu détaillé du langage, nous avons regardé les opérateurs, les commandes de contrôle et les fonctions de TorqueScript. Nous avons alors abordé comment utiliser les objets dans TorqueScript, en regardant leurs identifiants et, noms, champs et commandes, champs dynamiques, et méthodes de console. Ensuite, nous avons rapidement vu les packages, les espaces de nommage, et les datablocks. Nous avons tout d'abord couvert ces sections brièvement, afin d'en comprendre plus sur l'interaction entre le moteur et la 122 / 223 Documentation de Torque V1.3.x console de script avant de pouvoir entrer plus dans les détails. Après un regard détaillé sur le mécanisme d'interface moteur-console dans Torque, nous sommes revenu sur les datablocks, les objets et les espaces de nommage. Pour les datablocks en particulier, nous avons trouvé comment les datablocks et les objets sont en relation, et comment déclarer les datablocks. En étudiant les espaces de nommage, nous avons appris qu'ils peuvent être délicats, mais nous avons découvert les hiérarchies des espaces de nommage, et appris comment créer des espaces de nommage de datablock simple, et alors nous sommes devenus des maîtres dans l'espace de nommage de datablock. Si tout va bien, ce chapitre a été utile. Évidemment, nous étions incapables d'aller en profondeur sur chaque aspect de TorqueScript, mais vous devriez avoir un très bon aperçu du fonctionnement du langage, et être capable de revenir et d'étudier à nouveau ce guide pour des informations supplémentaires lorsque vous en aurez besoin. Pour de plus amples informations, allez dans les tutoriels de TorqueScript et les ressources. N'oubliez pas aussi les forums, et la grande communauté GarageGames. Une note finale : ce chapitre a été écrit par Ed Maurina, un membre exceptionnel de la communauté, avec le concours de l'équipe GarageGames. C'est un aperçu impressionnant du Guide essentiel du Torque Game Engine (EGTGE) de Ed Maurina disponible sur notre site Internet. 123 / 223 Documentation de Torque V1.3.x 5 Codage du moteur en C++ Ce chapitre est adapté du guide exceptionnel « Essential Guide Torque Game Engine (EGTGE) » de Edward Maurina. L'EGTGE devrait être lu par tous les développeurs. 5.1 Introduction 5.1.1 Torque et la documentation du moteur Torque est un grand logiciel. Vous n'avez travaillé jusqu'à maintenant qu'avec un fraction de Torque. Ce manuel de référence a été créé afin de vous donner – que vous soyez un développeur débutant ou un programmeur C++ expérimenté, ou quelque part entre les deux – une approche de la manipulation et des extensions de Torque. Ce document atteint deux objectifs. Premièrement, il fournit une liste de chaque variable, fonction, méthode, classes, espaces de nommage, et fichier du moteur. Vous pouvez passer littéralement des heures à parcourir la hiérarchie de classe de Torque; le TER (Torque Engine Reference) permet de focaliser beaucoup plus facilement sur la structure du code, au lieu de ce noyer dans les détails des fichiers source. Secondement, il contient des explications et des exemples qui peuvent effectivement fonctionner avec Torque. Il agit comme un guide pour le moteur, afin que vous préserviez votre temps lorsque vous cherchez une solution à un problème. Il vous aide aussi à faire les choses de manière correcte – afin de ne rien oublier, préservant vos efforts lors du débogage (et rendant votre jeu plus efficace). Cette documentation est orientée vers les développeurs C++. Si vous cherchez des informations sur comment utiliser les outils de support du moteur, ou comment travailler avec le langage de script ou les éditeurs, vous pouvez avec de meilleures chances en regardant à http://www.garagegames.com/docs/tge/. 5.1.2 Qu'ai je besoin de savoir ? Il serait formidable s'il était possible d'acheter Torque et, sans aucune connaissance préalable, commencer la création de jeux incroyables, à la technologie innovante... mais malheureusement, ceci n'est pas possible. L'écriture de moteurs de jeux est d'une compétence avancée. Heureusement, Torque est déjà écrit. Tout ce dont vous avez besoin est intégré dans ses fondations. Ainsi, que devez-vous savoir pour développer avec Torque ? Vous devez être capable de lire du code C ou C++. Vous devriez être familier avec les structures de données de base, comme les vecteurs, les listes liées, les arbres et les files d'attente. Vous devez être confortable avec les pointeurs et la gestion de la mémoire. Une bonne connaissance avec l'algèbre linéaire, ou au moins les bases du graphisme 3D, sera importante, ainsi qu'une compréhension des protocoles réseau et des fichiers E/S. Mais, vous dites, « Attendez, je n'ai pas prêté beaucoup d'attention à l'algèbre linéaire... Je n'aime pas les structures de données... » ou peut-être, êtes-vous juste un programmeur débutant. Suis-je en train de me mettre le doigt dans l'œil ? Nullement ! Vous avez en votre possession un des meilleurs moyens éducatifs que vous puissiez trouver. Vous apprendrez quelque chose en travaillant avec Torque. Collez-vous à moi – postez sur les forums et traînez sur l'IRC (Internet Relay Chat) – et vous trouverez par vous-même plus que vous ne pensiez possible. Lorsque j'ai commencé à travailler avec Torque, je pensais que j'étais un bon programmeur C++ – mais j'ai aisément doublé mes connaissances C++ en travaillant avec lui. N'abandonnez pas. Gardez vos esprits. Allez faire un tour lorsque vous voyez des SimObjects dansants devant vos yeux. Vous allez bien ! 5.1.3 Que dois-je faire si les documentations sont incomplètes Torque est, comme nous l'avons mentionné, un ensemble grand et complexe de code. Bien que nous ayons tous les efforts pour documenter tout le code dans le moteur, il est tout à fait possible que vous rencontriez des éléments non documentés, incomplètement documentés, ou faussement documentés. 124 / 223 Documentation de Torque V1.3.x C'est bon. Voici comment faire avec ceci : 1. Arrivez à comprendre ce qui se passe. Cela signifie que vous devez ouvrir les fichiers source et les parcourir, voir comment le code est étroitement lié. Prenez des notes, et cartographiez les appels de fonctions effectués, et les structures de données qui sont utilisées. 2. Si vous avez des questions, cherchez la sagesse auprès des canaux IRC de GarageGames, ou des forums. Il y a tas de gens qui ont probablement rencontré les mêmes problèmes ou assez similaires. Pour de meilleurs résultats, soyez sûr penser au problème – faites un effort réel pour le résoudre par vous-même. Les gens sont toujours plus disposés à aider s'ils peuvent voir que vous avez mis de sérieux efforts dans la résolution du problème. 3. À ce point, si tout va bien, vous avez résolu votre problème. S'il ne l'est pas, répétez les étapes 1 et 2. 4. Maintenant que vous comprenez ce qui se passe, ajoutez des documentations pour aider ceux qui viennent après vous ! Reportez-vous à http://www.garagegames.com/mg/projects/tge/contribute.php pour avoir les instructions sur la contribution de votre documentation. 5.1.4 Crédits Employés GarageGames : Mark Frohnmayer Rick Overman Tim Gift Internes GarageGames : Ben "Sado" Garney Pat "KillerBun" Wilson Chris "Hobbiticus" Weiland Collaborateurs : Pas encore – vous pouvez être le premier ! Envoyez un message à [email protected] avec vos ajouts à la documentation existante, ou vos nouvelles contributions. 5.2 Flux de contrôle de base 5.2.1 Introduction Puisque différentes plates-formes peuvent avoir différents points d'entrée main() pour les applications, la fonction main() du moteur de Torque réside dans la bibliothèque dépendant de l'OS cible. Dans le cas de Windows, c'est le fichier engine/platformWin32/winWindow.cc, où sont définis à la fois main() (pour l'application console) et WinMain(). Ceux-ci appelant à leur tour run() qui appelle Game->main(int argc, const char **argv). Game est un pointeur d'objet global référençant une instance de la classe GameInterface qui peut être surchargée pour un comportement de jeu spécifique. L'initialisation principale du programme d'exemple de Torque survient dans engine/game/main.cc dans DemoGame::main(). Cette fonction initialise les bibliothèques et les fonctions du jeu et alors entre en cycle dans la boucle principale du jeu jusqu'à ce que le programme se termine. La boucle principale appelle fondamentalement les fonctions de la bibliothèque de plate-forme (engine/platform/platform.h) pour gérer les événements, qui pilotent la simulation principale. Le fichier main.cc a aussi une fonction DemoGame surchargée pour certaines fonctions de traitement d'événements de base : processMouseMoveEvent (qui distribue les mouvements de la souris dans la fenêtre à la GUI), processInputEvent (qui traite les autres événements relatifs aux entrées), et processTimeEvent qui calcule une valeur de temps basée sur l'échelle de temps paramétrée pour la simulation et ensuite : • gère le temps pour les objets côté serveur (serverProcess() dans engine/game/game.cc) 125 / 223 Documentation de Torque V1.3.x • • • • • • traite les paquets réseau envoyés côté serveur (serverNetProcess() dans engine/game/netDispatch.cc) gère l'avance du temps des événements de la simulation (Sim::advanceTime() dans engine/console/simManager.cc) gère le temps pour les objets côté client (clientProcess() dans engine/game/game.cc) traite les paquets réseau envoyés côté client (clientNetProcess() dans engine/game/netDispatch.cc) rend graphiquement la trame courante (GuiCanvas::render() dans engine/gui/guiCanvas.cc) traite les délais d'attente du réseau (dispatchCheckTimouts() dans engine/game/netDispatch.cc) Les paquets réseau UDP entrants sont traités dans DemoGame::processPacketReceiveEvent (défini dans engine/game/netDispatch.cc), et la donnée ou l'information de connexion TCP entrante est traitée dans DemoGame::processConnected*Event (défini dans engine/game/TCPObject.cc). 5.3 Couche plate-forme 5.3.1 Aperçu La couche plate-forme est la fondation de Torque. Fonctionnant au plus bas niveau, elle fournit une plateforme et une interface d'architecture commune au système pour le jeu. La couche plate-forme est responsable de la gestion des E/S fichier et réseau, de l'initialisation graphique, de l'initialisation et des entrées des périphériques, et la génération des événements temporels. Les appels à la bibliothèque standard sont effectués au travers de la couche plate-forme, de sorte que le code du jeu puisse être préservé des spécificités de la plate-forme. Les fichiers d'en-tête système sont seulement inclus à partir de la bibliothèque plate-forme. La couche plateforme est décomposée en plusieurs sections – l'interface inter-plate-forme exposé au jeu (engine/platform), et la bibliothèque spécifique à la plate-forme (engine/platformWin32, engine/platformMacOS, engine/platformX86UNIX). 5.3.2 Modèle d'événement Le jeu est mené par un flux d'événements de la bibliothèque de plate-forme. En journalisant le flux d'événements de la couche plate-forme, la portion du jeu de la session de simulation peut être, de manière déterministe, rejouée dans un but de débogage. Les événements utilisés par la couche plate-forme sont tous des sous-classes de Event : • • • General Events • TimeEvent • QuitEvent • ConsoleEvent Input Events • InputEvent • MouseMoveEvent Networking • PacketReceiveEvent • ConnectedReceiveEvent • ConnectedAcceptEvent • ConnectedNotifyEvent 5.3.3 Utilitaires de plate-forme Torque a un nombre de bibliothèques d'utilitaires puissants dans la couche plate-forme : • • Le gestionnaire de mémoire (memory manager) – situé dans engine/platform/platformMemory.cc, il est conçu pour allouer rapidement de la mémoire, effectuer des tests de débordements, libérer les blocs libres et les fuites de mémoire. Le profileur (profiler) est une trousse à outils d'analyse de temps qui permet à des portions spécifiques du jeu d'être « chronométrées » – utile pour trouver les goulots d'étranglement au niveau 126 / 223 Documentation de Torque V1.3.x • • des performances. Le gestionnaire de processus (thread managment), Torque a des classes pour la création de threads20, mutex21, et sémaphores22. La bibliothèque standard – toutes les fonctions de la bibliothèque standard sont redéfinies comme les fonctions d...(), par exemple, sprintf devient sSprintf(), strcpy devient dStrcpy(), etc. Les fonctions d...() tirent pleinement avantage des fonctionnalités de Torque, et sont garanties de fonctionner de la même manière, quelle que soit la plate-forme; contrairement aux fonctions remplacées qui peuvent ne pas l'être. 5.3.4 Fonctionnalité réseau La bibliothèque plate-forme a une interface commune pour l'ouverture et la fermeture des ports réseau, la connexion à d'autres serveurs, la conversion d'adresse réseau, et l'envoi et la réception de données réseau. TCP et UDP sont supportés. 5.3.5 GameInterface (Interface de jeu) La classe GameInterface définie dans engine/platform/gameInterface.h, est l'interface au travers de laquelle la plate-forme et les bibliothèques communiquent avec le jeu, aussi bien que le gestionnaire principal pour la journalisation. Tous les événements plate-forme passent au travers de GameInterface::processEvent() qui, à tour de rôle, alimente des gestionnaires virtuels d'événements. Une et une seule instance de cette classe (ou sous-classe) devrait exister dans le programme. Un unique pointeur global nommé Game pointe dessus. 5.4 Console 5.4.1 Aperçu Le module console, situé dans engine/console/console.h, est à la fois un compilateur et un interpréteur qui sert de fondation à l'application Torque. Tous les GUI, objets de jeu, interfaces et logiques de jeu sont gérés au travers de la console. Le langage lui-même est syntaxiquement similaire à un C++ non typé, avec quelques fonctionnalités supplémentaires qui permettent des développements de mod plus aisément. Les scripts de console peuvent être chargé via la commande console exec() à partir de la fenêtre console (affichée en utilisant la touche ~) ou ils peuvent être automatiquement chargés à partir d'un mod via le main.cs de ce mod. 5.4.2 Référence du langage console Le module de lecture et d'analyse du langage de la console Torque a été construit en utilisant les outils lex et yacc. Les fichiers de lecture et de grammaire sont respectivement engine/console/scan.l et engine/console/gram.y. La grammaire est indiquée avec un aspect un peu plus compréhensible dans le document joint. 5.4.3 Les fonctions Les fonctions console peuvent être déclarées soit dans ces scripts console, soit dans le code du jeu/moteur C++. // Une déclaration simple de fonction de script. function helloWorld() { echo("Bonjour a tous!"); } 20 Les processus légers (en anglais, thread), également appelés fils d'exécution, sont similaires aux processus en cela qu'ils représentent tous deux l'exécution d'un ensemble d'instructions d'un processeur. Du point de vue de l'utilisateur, ces exécutions semblent se dérouler en parallèle. Toutefois là où chaque processus possède sa propre mémoire virtuelle, les processus légers appartenant au même processus père partagent une même partie de sa mémoire virtuelle. (Wikipédia) 21 Un mutex (anglais : Mutual exclusion, Exclusion mutuelle) est une primitive de synchronisation utilisée en programmation pour éviter que des ressources non partagées d'un système soient utilisées en même temps. (Wikipédia) 22 Un sémaphore est une variable protégée et constitue la méthode utilisée couramment pour restreindre l'accès à des ressources partagées (par exemple un espace de stockage) dans un environnement de programmation concurrente (Wikipédia) 127 / 223 Documentation de Torque V1.3.x // Appelons la ! helloWorld(); // Ou, pour une méthode d'une classe : function SimObject::helloWorld(%this) { echo("Bonjour a tous !"); echo("Appele par l'objet : " @ %this); } // et appelons la... $object = new SimObject(); $object.helloWorld(); Contrairement au C++, la variable this n'est pas implicite dans une déclaration de méthode de script. Au lieu de cela, le premier paramètre d'une méthode est toujours l'objet appelant cette méthode. Il est traditionnel, mais non obligatoire d'appeler ce paramètre %this; une variante courante est %db, pour les méthodes des datablocks. Pour déclarer des fonctions console dans le code du jeu ou du moteur, la macro ConsoleFunction (déclarée dans engine/console/console.h) devrait être utilisée : ConsoleFunction(helloWorld, void, 1, 1, "Une simple fonction de test.") { Con::printf("Bonjour à tous !"); } Parcours des arguments de la macro ConsoleFunction : • • • En premier, on a le nom de la fonction, suivi pas le type. Ensuite, on donne le nombre minimum et le nombre maximun d'arguments autorisés. Le nom de la fonction est 'argument0', ainsi 1 le nombre minimum d'arguments autorisés. En passant un 0 pour le maximum, cela permet d'avoir un nombre quelconque d'arguments pour la fonction. Pour finir, la chaîne usage. Elle a deux buts. La chaîne, le plus souvent, existe pour fournir un retour à l'utilisateur s'il fait un appel à la fonction console avec un nombre incorrect d'arguments. Les méthodes pour les classes peuvent aussi être déclarées en C++, en utilisant la macro ConsoleMethod : ConsoleMethod(SimObject, helloWorld, void, 2, 2, "Un methode de test un peu plus complexe.") { Con::printf("Bonjour a tous!"); Con::printf("Appele par l'objet : %s", argv[1]); Con::printf("Aussi appele par l'objet : %s", object->getName()); } Ceci définit une méthode accessible par n'importe quelle instance de SimObject auquel la console a accédé. Trois paramètres utiles sont fournis au code dans le corps de ConsoleFunction ou ConsoleMethod : • • • int argc, indiquant combien d'arguments sont passés. const char* argv[], un tableau de chaînes correspondant aux arguments. object, qui est présent seulement dans le cas de ConsoleMethod, est un pointeur sur l'objet appelant la méthode. Il est automatiquement converti et validé ainsi, vous n'avait pas besoin de le convertir vous-même (ce qui n'était pas le cas dans les anciennes versions de Torque). 5.4.4 Les classes, objets et espaces de nommage 128 / 223 Documentation de Torque V1.3.x 5.4.4.1 Déclaration des classes console Les objets dans le langage de script sont simplement des instances de classes C++ dérivées de SimObject, déclarées dans le moteur de jeu et traitées avec un ensemble de macros spéciales (déclarées dans engine/console/consoleObject.h). La macro DECLARE_CONOBJECT(nom_classe) est placée dans la définition de classe et IMPLEMENT_CONOBJECT(nom_classe) est placée dans un fichier source lié. IMPLEMENT_CONOBJECT a plusieurs versions, dépendant du type de classe : IMPLEMENT_CONOBJECT() Un simple objet console – pas d'attribut réseau spécial. IMPLEMENT_CO_NETOBJECT_V1() Une classe d'objet réseau clonable. N'importe quel objet qui sera cloné du serveur au client doit être déclaré en tant que NETOBJECT. Voir la section sur la couche réseau pour plus de détails sur NetObjects. IMPLEMENT_CO_DATABLOCK_V1() Une classe datablock. Les datablocks ont des propriétés spéciales pour être transmises sur le réseau. Il y a trois IMPLEMENT_CONOBJECT de plus qui s'occupent spécifiquement des événements réseau. Ils ne sont pas abordés ici. Chaque classe, déclarée comme une classe Console, DOIVT déclarer un typedef de Parent dans sa section member privée référençant sa classe parente. Ceci permet à la console de déterminer correctement la hiérarchie de classe d'objets console pour les méthodes réparties dans la console. // Un exemple très simple de SimObject. class SampleObject : public SimObject { typedef SimObject Parent; public: DECLARE_CONOBJECT(SampleObject); S32 someVariable; // variable entière signée }; IMPLEMENT_CONOBJECT(SampleObject); Vous pouvez instancier et manipuler cet objet dans un script ainsi : function foo() { %obj = new SampleObject(MySampleObject); echo(%obj.getName()); } 5.4.4.2 Ajout de champs membres de classe Les membres de données de classe C++ peuvent être accédé à partir du langage de script. Lorsque le jeu commence, la console appelle AbstractClassRep::initialize(), qui assigne les identifiants (ID) réseau aux classes, lie les hiérarchies de classe, et initialise les champs de données pour chaque classe. Pour faire ceci, chaque classe avec des membres de données accessibles déclare une fonction de membre statique appelée initPersistFields(). Cette fonction appelle la fonction de membre statique addField pour chaque membre de données de la classe : 129 / 223 Documentation de Torque V1.3.x void SampleObject::initPersistFields() { Parent::initPersistFields(); // ajoute les champs de la classe parente. addField("someVariable", TypeS32, Offset(someVariable, SampleObject)); } Le type doit être correctement spécifié, bien sûr. La macro Offset est utilisée pour déterminer l'adresse relative du membre de données de la classe. Une fois que ceci est défini, les scripts peuvent directement utiliser le champ membre de l'objet : function bar() { %obj = new SampleObject(MySampleObject); %obj.someVariable = 100; echo(%obj.someVariable); } Les types de champ sont déclarés dans engine/console/consoleTypes.h. De nouveaux types de données de console peuvent être ajoutés en ajoutant un type dans consoleTypes.h et en appelant Con::registerType(typeId, typeSize, getDataFunc, setDatafunc). Voir engine/console/consoleTypes.cc pour des exemples sur la définition des types. 5.4.4.3 Champs définis dynamiquement Les champs de membre d'objets peuvent aussi être définis dans le script lui-même. Par exemple : function foo() { %object = new SampleObject(); %object.scriptVariable = "Bonjour à tous !"; echo(%object.scriptVariable); } Les champs ajoutés de cette manière sont seulement initialisés et présents dans l'instance dans laquelle ils ont été initialisés. 5.4.4.4 Espaces de nommage Les espaces de nommage (engine/console/consoleInternal.h) sont des collections de fonctions de membre de classe. Chaque SimObject appartient à exactement un espace de nommage. Par défaut, un objet appartient à l'espace de nommage correspondant à sa classe – ainsi, une instance de GameBase aura l'espace de nommage GameBase. Chaque espace de nommage a un parent ainsi, les méthodes peuvent invoquer des méthodes de classe parente en appelant Parent;;function(). De nouveaux espaces de nommage (non basé sur une classe) peuvent être ajoutés dans le moteur via la fonction Con::linkNamespaces(). Assigner le champ mNameSpace de SimObject assigne alors le nouvel espace de nommage à un objet. Par exemple, dans GuiControl::onAdd(), si un contrôle a un nom, son nom est utilisé en tant qu'espace de nommage. Ceci permet à un contrôle GUI nommé d'avoir des comportements spéciaux. La classe ScriptObject (définie dans engine/console/scriptObject.cc) permet la création de classes dans le langage de script : new ScriptObject(MyObject) { class = Bar; superClass = Foo; }; function Bar::doSomething(%this) { echo("Hi!"); 130 / 223 Documentation de Torque V1.3.x } MyObject.doSomething(); > Hi! function Foo::doSomething(%this) { echo("Hi! Foo"); } function Bar::go(%this) { %this.doSomething(); Parent::doSomething(%this); } MyObject.go(); > Hi! > Hi! Foo Chaque SimObject dans le système peut être adressé soit par son nom, soit par son ID. Ainsi dans l'exemple précédent, MyObject.go() cherche dans le dictionnaire des objets, un objet nommé MyObject et appelle la méthode go() de cet objet. 5.4.5 Les packages Les packages sont des collections de fonctions qui peuvent être activées ou désactivées durant l'exécution. Les fonctions de packages peuvent surcharger (redéfinir) le comportement des fonctions existantes dans la déclaration globale ou dans les packages qui ont été activés plus tôt. Les versions antérieures d'une fonction peuvent être accédé en utilisant 'Parent'. Par exemple : function foo() { echo("foo!"); } package SamplePackage { function foo() { echo("Haha!"); Parent::foo(); } } % foo(); foo! % ActivatePackage(SamplePackage); % foo(); Haha! foo! Les packages sont utiles pour la création de mods dans les jeux ou pour l'implémentation de modes de jeu spécifiques. 5.4.6 Les variables 131 / 223 Documentation de Torque V1.3.x Le langage supporte les variables globales et locales (contexte de fonctions). Les variables globales sont spécifiées en préfixant par $, et les variables locales par %. Exemple : $someGlobal = "Ceci est global."; function foo(%local1, %local2) { %local3 = $someGlobal; } function bar(%local) { // Vous pouvez aussi créer une nouvelle variable globale dans une fonction. $alottaGlobal = %local @ " is."; } 5.4.7 Les tableaux Le langage supporte les tableaux simples et multidimensionnels. Actuellement, les tableaux construisent de nouvelles variables avec le nom concaténé – par exemple $array[10] est la même chose que $array10, tandis que $array[3,4] est la même chose que $array3_4. Les chaînes peuvent être aussi bien utilisées comme index de tableaux : $array["foo"] = 100;. Les dimensions des tableaux sont séparées par des virgules – $array[1,0] = 10; 5.4.8 Les opérateurs spéciaux de chaîne Il y a plusieurs opérateurs spéciaux pour les chaînes dans le langage de script : • • • • • • $= – comparaison d'égalité de chaîne insensible à la casse. True si les chaînes sont égales. !$= – comparaison d'inégalité de chaîne insensible à la casse. True si les chaînes sont inégales. @ – opérateur de concaténation de chaînes. "Hello " @ "World!" == "Hello World!" TAB – concaténation de chaînes avec une tabulation. "Hello" TAB "World!" == "Hello\tWorld!" NL – concaténation de chaînes avec une tabulation. "Hello" NL "World!" == "Hello\nWorld!" SPC – concaténation de chaînes avec une tabulation. "Hello" SPC "World!" == "Hello World!" 5.4.9 Le compilateur Les scripts sont exécutés en deux étapes : premièrement, le script est compilé en un flux d'instructions codées, ensuite le flux d'instructions est traité en utilisant l'évaluateur compilé. 5.4.10 Le débogueur La console supporte le débogage distant via une autre instance de Torque. Dans l'instance du jeu devant être déboguée, le port et mot de passe du débogueur doivent être initialisés en utilisant dbgSetParameters(port,password); Ensuite, dans l'instance devant être utilisé comme débogueur, les GUIs et les scripts de common/debugger/ doivent être chargés. 5.4.11 Interface avec le code C++ Le code C++ du jeu et du moteur peut être appelé à partir des scripts comme décrit précédemment, et le code du jeu peut aussi appelé du script en utilisant les fonctions d'exécution et d'évaluation console. // exécution simple d'une fonction console utilisant un tableau argv : const char *execute(S32 argc, const char* argv[]); // exécution simple d'une fonction console, sans utiliser de tableau 132 / 223 Documentation de Torque V1.3.x const char *executef(S32 argc, ...); // exécution d'une méthode d'un SimObject en utilisant un tableau argv : // le premier paramètre est le nom de la fonction, // le second paramètre DOIT être vide, // vous DEVEZ avoir au moins ces deux paramètres const char *execute(SimObject *, S32 argc, const char *argv[]); // exécution d'une méthode d'un SimObject sans utiliser de tableau // le premier paramètre est le nom de la fonction, // les paramètres restant sont args const char *executef(SimObject *, S32 argc, ...); // évaluation d'un script de commandes console an arbitraire : const char *evaluate(const char* string, bool echo, const char *fileName); // évaluation d'une chaîne de commandes formatée (comme printf) : const char *evaluatef(const char* string, ...); Exemples : SimObject *mySimObject = new SimObject; Con::executef(mySimObject, 4, "doSomething", Con::getIntArg(20), "Bye", "Hi"); Con::evaluatef("mySimObject.doSomething(%d,\"%s\",\"%s\");", 20, "Bye", "Hi"); const char *argv[5]; argv[0] = "doSomething"; argv[1] = NULL; argv[2] = Con::getIntArg(20); argv[3] = "Bye"; argv[4] = "Hi"; Con::execute(mySimObject, 5, argv); Les fonctions Con::getIntArg, Con:getFloatArg et Con::getArgBuffer(size) sont utilisées pour allouer, sur la pile de la console, les variables de chaîne qui seront passées à la prochaine fonction console appelée. Ceci permet à la console d'éviter de copier quelques données. 5.5 Simulation 5.5.1 Introduction La simulation des objets est gérée presque entièrement dans la portion jeu du moteur. Toutes les classes d'objet de simulation sont dérivées de GameBase, qui est une sous-classe de SceneObject. Les objets GameBase souhaitant être informés de l'écoulement du temps peuvent être ajoutés à l'une des deux listes – la liste des processus globaux serveur et la liste des processus globaux clients, dépendant si l'objet est un objet serveur ou un objet client. Tous les objets dans la liste des processus sont « sollicités » toutes les 32 millisecondes. Le classement des objets est déterminé par la méthode GameBase::processAfter, qui est appelée si un objet doit être traité à un moment donné après un autre objet (pas nécessairement après). Par exemple, un joueur à bord d'un véhicule devrait être traité après le véhicule, de sorte qu'après le déplacement du véhicule, la position du joueur puisse être mise à jour dans une position correcte par rapport à celle du véhicule. 5.5.2 Interfaces de mise à jour Les objets Game sont mis à jour par trois fonctions distinctes, surchargées de GameBase : GameBase::processTick(), qui prend comme argument une seule structure Move (elle peut être NULL) et 133 / 223 Documentation de Torque V1.3.x avance l'objet d'une unité de temps (Tick23) de 32 millisecondes. GameBase::interpolateTick(), qui interpole un objet client de la fin de son tick courant jusqu'à l'instant présent, et GameBase::advanceTime(), qui permet à un objet client d'effectuer des animations et des effets au travers de la durée totale de l'événement temporel. Les objets côté serveur sont uniquement simulés que sur les limites de ticks, mais les objets client, afin de présenter une vue douce lorsque le taux d'images est élevé, sont simulés après chaque événement temporel. GameBase::processTick est encore uniquement appelé sur les limites de ticks, mais à la fin de l'avance du temps, les objets sont essentiellement rembobinés sur la différence de temps avec la fin du tick. En outre, les objets client, nécessitant d'être animés uniquement sur le temps total écoulé, peuvent faire ainsi dans la fonction GameBase::advanceTime qui n'est appelée qu'une seule fois par avancement temporel. Si l'objet de contrôle envoie l'état d'un nouvel objet à partir du serveur, il sera avancé par chaque Move que le client a enregistré que le serveur n'a pas encore reconnu – car le serveur a les anciennes données tant que le client est concerné, ainsi le client parcourra toutes les nouvelles données qu'il connaît. 5.5.3 Objets de simulation SimBase (engine/console/simBase.*) définit les classes fondamentales de SimObject que forment la base du moteur de simulation. SimObject est la classe de base de tous les objets que le langage console peut créer et manipuler. Toutes les classes du jeu (Player, InteriorInstance, Terrain, etc.) et les classes GUI (GuiCanvas, GuiControl, etc.) sont toutes dérivées de SimObject. SimObject maintient la liste des champs dynamiques, a des propriétés de nom et d'ID, et peut s'enregistrer lui-même avec un gestionnaire d'objet global, fournissant aussi bien plusieurs autres services. Un SimSet est une simple collection de SimObjects. L'ensemble a des méthodes console pour l'ajout et la suppression d'objets et l'itération de l'ensemble. Un SimGroup est un dérivé de SimSet qui « possède » les objets dans sa collection. Lorsqu'un objet SimGroup est détruit, il détruit l'ensemble de ses membres. Le GuiControl est dérivé de SimGroup – de ce fait de GUI un ensemble hiérarchique d'objets. SimEvent est une classe spéciale d'objets pouvant être utilisée pour envoyer des messages retardés aux objets. SimManager (engine/console/simManager.cc) est une collection de fonctions pour la gestion de tous les objets et événements dans la simulation. Les objets sont assemblés dans une hiérarchie de SimGroups et peuvent être cherchées par nom ou par ID. 5.5.4 Persistance et inspection Les objets dans Torque peuvent être sauvegardés dans un fichier de script en utilisant SimObject::save(). Ceci décharge l'état courant de tous les champs et champs dynamiques inscrits des objets, aussi bien que, dans le cas d'un SimGroup, tous les sous-objets de ces objets. Les GUI et les missions sont des exemples de comment les éditeurs du moteur sauve les objets. Les champs des objets peuvent également être modifiés dans le jeu en utilisant l'inspecteur, qui est une fenêtre GUI qui montre les champs d'un objet et permet à ces champs d'être modifiés et sauvegardés. Avant que les nouvelles valeurs des champs soient sauvegardées dans un objet, sa méthode onPreApply() sera appelée, puis les champs seront modifiés, ensuite la méthode onPostApply() de l'objet sera appelée. 5.5.5 Les commandes console utiles Il a plusieurs commandes console qui sont utiles pour avoir une idée de ce qui se passe dans le système : 23 Tick : Unité de mesure du temps. Un tic ou un tac dans le tic-tac d'une l'horloge d'un ordinateur ou d'un timer. Pratiquement toujours au pluriel, car un tick est très court : de l'ordre d'un millionième ou un milliardième de seconde pour une horloge, ou d'un millième de seconde pour un timer. 134 / 223 Documentation de Torque V1.3.x trace(true); trace(false); // Active le mode trace // Désactive le mode trace tree(); // // // // // // object.dump(); set.listObjects(); Affiche un inspecteur graphique de hiérarchie et d'objet pour tous les objets actuellement enregistrés dans le système. Copie une liste de toutes les commandes console et variables d'instance d'un objet. Liste tous les objets dans un ensemble. 5.5.6 Base de données de Container Les Containers contiennent une base de données à la fois sur le client et le serveur pour les objets placés dans la simulation. Ils supportent un jeu de fonctions pour l'insertion, la suppression et le déplacement rapide d'objets dans le monde (Container::addObject, Container::removeObject, Container::checkBins), aussi bien que des fonctions de requête pour les tests d'intersection de lignes, de boîtes et de polyèdres (Container::castRay, Container::collideBox, Container::findObjects). 5.6 Fichiers, flux et gestionnaire de ressources 5.6.1 Aperçu Le moteur de Torque utilise beaucoup de ressources – fichiers de terrain, images, formes, listes de matériaux, polices et intérieurs, pour ne citer que quelques exemples. Afin de gérer effectivement un grand nombre de ressources de jeu et fournir une interface commune pour le chargement et la sauvegarde des ressources, Torque utilise le ResManager. Les ressources ont la propriété spéciale dont seule une instance d'une ressource sera chargée à la fois. Les objets de ressource ont des références comptabilisées de sorte que lorsqu'une seconde requête est effectuée sur la même ressource, l'instance originelle chargée est retournée. Le gestionnaire de ressource définit aussi une classe modèle de ressource qui agit comme un pointeur transparent vers divers types de ressources de jeu. 5.6.2 Chemins de recherche Une liste des chemins de recherche est alimentée pour le ResManager via la fonction setModPaths(). Cette fonction balaye également les chemins indiqués pour tous les fichiers y étant placés, créant un ResourceObject pour chacun d'eux. Ils sont tous stockés dans un ResDictionary, permettant une recherche rapide pour un fichier donné. En plus, un chemin d'écriture peut être renseigné en utilisant setWriteablePath(). Ce chemin est utilisé pour stocker les fichiers téléchargés des serveurs de jeu. 5.6.3 Fichiers Volume Le système ressource supporte également les fichiers Volume, qui sont apparus avec « Tribes 1 » comme fichiers .vol et « Tribes 2 » comme fichiers .vl2, mais sont en réalité des fichiers ZIP. Lorsque le ResManager rencontre un fichier avec l'extension .zip, il l'ouvre et ajoute tous les éléments dans la table des matières du ZIP à la liste des fichiers connus. ResManager gère automatiquement les complexités liées à l'ouverture d'un fichier ZIP et au traitement d'un fichier spécifique y étant inclus ainsi, l'implémentation de votre ressource n'a pas à se préoccuper d'où viennent les données. 5.6.4 Ressource et ResourceObjets Comme indiqué précédemment, le ResManager maintient une liste de tous les fichiers qu'il connaît employant des ResourceObjects. Le ResourceTemplate est fourni pour gérer les références aux ResourceObjects; il s'assure que la ressource soit correctement comptabilisée et référencée. 135 / 223 Documentation de Torque V1.3.x 5.7 Modèle d'entrée 5.7.1 Aperçu Les événements d'entrée viennent de l'OS, sont traduits dans la couche plate-forme et alors envoyé vers le jeu. Par défaut, le jeu vérifie alors l'événement d'entrée contre une carte d'actions globale (qui surpasse tous les autres gestionnaires d'entrée). Si aucune action n'est spécifiée pour l'événement, il est passé au système GUI. Si la GUI ne gère pas l'événement d'entrée, il est passé à la pile actuellement active de cartes d'actions (non globale). Exemple : l'utilisateur appuie sur la touche ~ (tilde), qui est liée à la carte d'actions globale (dans example/client/scripts/default.bind.cs) à toggleConsole. Ceci implique l'exécution de la fonction console associée avec le lien, qui dans ce cas est toggleConsole, et qui affiche la fenêtre d'affichage console. Si la touche n'a pas été liée dans la carte globale, elle passerait à la première GUI qui pourra la gérer, et si cela n'est pas, elle passerait à n'importe quelle action qui serait liée à cette touche. 5.7.2 Entrée plate-forme Le code spécifique à la plate-forme traduit les événements spécifiques à l'OS en événements uniformes d'entrée Torque; Ces événements sont postés dans la queue d'événements de l'application principale via un appel à GameInterface::processEvent() (rappelez-vous, Game pointe sur une sous-classe de GameInterface). Le comportement par défaut pour la classe GameInterface est de passer tous les événements d'entrée à GameInterface::processInputEvents(), qui, dans l'exemple DemoGame appelle ActionMap::handleEventGlobal, suivit par Canvas->processInputEvent (si non géré par la carte globale), et si ni l'un ni l'autre ne le gère, le passe à ActionMap::handleEvent. 5.7.3 Cartes d'actions Les cartes d'actions tracent la carte des événements d'entrée de plate-forme pour les commandes console. N'importe quel événement d'entrée plate-forme peut être lié d'une seule manière générique – ainsi, en théorie, le jeu n'a pas besoin de savoir si l'événement provient du clavier, de la souris, de la manette de jeu ou d'un autre périphérique. Ceci permet aux utilisateurs du jeu de redéfinir les touches et les actions en fonction de leurs préférences. Il y a un objet ActionMap défini qui est traité en premier pour tous les événements appelés GlobalActionsMap. Les cartes d'actions de jeu sont disposées dans une pile pour le traitement – ainsi, des parties du jeu peuvent définir des actions spécifiques – par exemple lorsque le joueur saute dans un véhicule, il peut pousser une carte d'actions de véhicule et récupérer la carte d'actions de joueur par défaut. 5.7.4 Touches modificatrices Le inputName d'une action peut être modifié par une des trois touches modificatrices – alt, majuscule (shift) et contrôle (control). Par exemple, la bascule entre mode plein écran/fenêtre à < alt + entrée >. Si une action est appelée avec un modificateur, libérez-la ou les touches modificatrices ne causeront pas l'arrêt de l'événement à activer – seulement si la touche elle-même est libérée. 5.8 Graphismes 5.8.1 Aperçu Le moteur de Torque n'implémente pas sa propre couche de trames graphiques. OpenGL a été choisi comme API graphiques pour Torque, principalement pour sa nature multiplates-formes et son utilisation aisée. Torque inclut une bibliothèque d'utilitaires appelée DGL qui étend OpenGL pour supporter les primitives et les ressources de haut niveau, aussi bien que réaliser la gestion des textures. La couche plate-forme est responsable de l'initialisation d'OpenGL. Pour PlatformWin32, ceci peut inclure le chargement d'une DLL qui convertit les appels OpenGL en Direct3D (OpenGL2D3D.DLL). 136 / 223 Documentation de Torque V1.3.x 5.8.2 Le gestionnaire de textures (Texture Manager) DGL inclut un gestionnaire de textures (engine/dgl/dTexManager.*) qui s'occupe des chargements et déchargements de toutes les textures dans le jeu. Lorsque le jeu réclame une texture, il utilise la classe TextureHandle – qui agit comme une sorte de gestionnaire de ressources spécial pour les textures dans le jeu. Une seule instance d'une texture est chargée à la fois, et après chargement, est gérée par OpenGL. Lorsque le jeu bascule entre modes graphiques ou périphériques vidéo, le gestionnaire de textures peut recharger et télécharger de nouveau, de manière transparente , toutes les textures du jeu. 5.8.3 Support des primitives Gfont – les polices de caractères dans Torque sont des textures alpha créées par la couche plate-forme à partir des polices vectorielles dépendant de l'OS. Gbitmap – Torque supporte plusieurs types de fichier bitmap – PNG, JPEG, GIF, BMP et le format BM8 (un format de textures quantifiées sur 8 bits, utilisé pour réduire la perte de mémoire de textures). MaterialList – une liste des matériaux dans une ressource qui gère une liste des bitmaps. Il est toujours pour les formes et les intérieurs ayant plus d'une texture. 5.8.4 Primitives de rendu Les fonctions de support DGL supportent une large variété de primitives de rendu 2D communes. Les bitmaps (chargés comme textures) peuvent être rendus via les fonctions dglDrawBitmap(), dglDrawBitmapStretch(), dglDrawBitmapSR() (sous-région), et dglDrawBitmapStretchSR(). Les textes peuvent être rendus en utilisant dglDrawText() et dglDrawTextN(). DGL supporte aussi le tracé de lignes, de rectangles et de rectangles pleins. À la différence de l'OpenGL par défaut, l'espace de coordonnées de l'écran établi pour le rendu 2D dans Torque est un schéma traditionnel 2D où (0,0) est le coin supérieur gauche avec l'axe Y (0) dirigé vers le bas. Ceci requiert (dans le cas de la 3D) d'appeler dglSetViewport plutôt que glViewport. Pour le rendu 2D, la gestion de la fenêtre DGL est simplifiée par dglSetClipRect(). 5.8.5 Rendu 3D Il y a plusieurs différences clefs dans la manière dont Torque effectue le rendu par rapport à l'OpenGL par défaut. Premièrement, le système de coordonnées est établi avec l'axe Y (+) vers le bas à la place de l'axe Z (-). Cela signifie que DGL remplace l'appel à glFrustum() par un appel à dglSetFrustum(). En outre, toutes les matrices de Torque sont organisées dans une forme de tableau C standard – avec le second élément du tableau correspondant à la première ligne, seconde colonne. Ceci est le contraire d'OpenGL , ainsi DGL fournit des alternatives à glLoadMatrix() et glMultMatrix(), respectivement nommées dglLoadMatrix() et dglMultMatrix(). Les points 3D peuvent être convertis en points d'écran 2D en utilisant la fonction dglPointToScreen(), et une mesure de la taille projetée d'un objet à l'écran peut être déterminée en utilisant la fonction dglProjectRadius(). 5.9 L'interface graphique utilisateur (GUI) 5.9.1 Aperçu La bibliothèque GUI gère l'interface utilisateur des applications de Torque. Basée très lâchement sur la bibliothèque de classes de l'interface de NeXTSTEP, la bibliothèque GUI est conçue spécifiquement pour les besoins de développement d'interface utilisateur de jeu. Quelques classes importantes : • GuiCanvas – l'objet Canvas, une instance singleton de la classe GuiCanvas, est la racine de la hiérarchie GUI active en cours. Elle est responsable du traitement et de la distribution des événements souris et clavier, de la gestion de la mise à jour des régions et de la gestion du curseur, de l'appel à la méthode de rendu GuiControl, lorsque c'est le moment de tracer l'image suivante. 137 / 223 Documentation de Torque V1.3.x GuiCanvas maintient une pile de contrôle de contenu – les hiérarchies séparées des GuiControls qui effectuent le rendu du bas vers le haut. Le contrôle de contenu principal est un écran, et peut être recouvert par n'importe quel nombre de fenêtres et de boîtes de dialogue. La racine de chaque hiérarchie de contrôle de contenu est dimensionnée pour recouvrir entièrement le canvas ainsi, généralement, les dialogues sont composés d'un contrôle de contenu contenant un contrôle dialogue. • GuiControlProfile – Les instances de classe GuiControlProfile maintiennent des données communes d'instance à travers un ensemble de contrôles. Les informations communes telles le nom de la police de caractères, les bitmaps et les données sonores sont tous stockés dans des instances de GuiControlProfile, ainsi elles n'ont pas besoin d'être dupliquées dans chaque contrôle. • GuiControl – La classe GuiControl est la classe racine pour tous les contrôles GUI dans le système. Le GuiControl est dérivé de SimGroup et peut contenir n'importe quel nombre de contrôles GUI enfant. Chaque GuiControl maintient un rectangle d'encadrement dans le système de coordonnées de son contrôle parent. GuiControl a les méthodes virtuelles pour le traitement des événements d'entrée (onMouseDown, onMouseUp, onMouseEnter, onMouseLeave, onMouseMove, onMouseDragged, onRightMouseDown, onKeyDown, onKeyUp, onKeyRepeat), les méthodes appelées par le Canvas pour le rendu (onPreRender, onRender), les méthodes pour contrôler le verrouillage du focus de la souris (mouseLock, mouseUnlock), les méthodes de conversion de coordonnées (localToGlobalCoord, globalToLocalCoord), et le comportement automatique du dimensionnement lorsque son contrôle parent est redimensionné (par exemple, lorsque la résolution de l'écran change). Lorsqu'un contrôle est rendu visible, il (s'il n'est pas déjà chargé) charge les données associées avec son GuiControlProfiles. 5.9.2 Traitement des événements d'entrée dans le système GUI Les événements d'entrée sont traités en premier pour la distribution dans GuiCanvas::processInputEvent. Dépendant du type d'événement d'entrée (clavier ou souris), le Canvas traite l'événement de différentes manières. Pour les événements clavier, le Canvas maintient une variable d'instance appelée le premier répondeur (mFirstResponder). Le premier répondeur est principalement le contrôle qui a le focus clavier – par exemple, un champ texte dans lequel l'utilisateur saisit ou un bouton que l'utilisateur a tabulé. Pour n'importe quel événement clavier, le premier répondeur a la première chance de traitement. S'il ne le traite pas, l'événement est passé à sa classe parent et ensuite GuiControl, pour finir, à son contrôle parent. Si l'événement clavier n'est géré par aucun contrôle dans la chaîne des répondeurs (à partir du premier répondeur jusqu'au contrôle de contenu racine), le Canvas teste pour voir s'il y a une touche spéciale – tab et shift-tab déterminent le premier répondeur sur le contrôle respectivement suivant et précédent dans la liste tab. S'il n'est pas tab ou shift-tab, le Canvas teste pour voir si la touche est dans la carte d'accélérateur pour n'importe quel contrôle visible (par exemple, un bouton OK affecté à la touche Entrée). Si elle n'est pas affectée, le Canvas retourne false, signifiant que l'événement devrait être traité par le gestionnaire de carte d'action. Pour les événements souris (si le curseur est actif), l'événement est géré par le système GUI. Chaque événement souris peut potentiellement générer plusieurs appels aux méthodes virtuelles des contrôles. Par exemple, déplacer le curseur de la souris d'un contrôle dans un autre fera que le premier contrôle recevra un appel à la méthode OnMouseLeave, suivi par un appel à la méthode onMouseEnter du nouveau contrôle et pour finir un appel à onMouseMouve de ce même contrôle. GuiControls peut verrouiller le focus de la souris sur le canvas de sorte que seul ce contrôle reçoive les invocations des méthodes de souris – par exemple, le contrôle GuiButtonCtrl verrouille la souris lors de l'appui sur son bouton et la déverrouille lors du relâchement du bouton de sorte que si l'utilisateur déplace le curseur en dehors du contrôle, le GuiButtonCtrl conserve encore le focus et peut se réactiver lorsque le curseur revient dessus. La méthode virtuelle pointInControl de GuiButtonCtrl retourne par défaut true si le curseur est dans le rectangle limitant le contrôle. La sous-classe Control avec des formes non rectangulaires peut surcharger cette méthode pour fournir des contrôles avec des limites irrégulières d'action de souris. 5.9.3 Rendu des contrôles dans le système GUI L'objet Canvas est la racine de la hiérarchie de rendu des contrôles et il est responsable du processus de rendu. Lorsque le jeu reçoit un événement temporel de la couche plate-forme, il avance l'état de la simulation et alors informe le Canvas lui-même d'effectuer son rendu. Avant d'effectuer réellement le rendu, le Canvas 138 / 223 Documentation de Torque V1.3.x informe chaque contrôle à l'écran via onPreRender(), permettant à chaque contrôle de déterminer si quelque chose a besoin d'être rendu sur ce contrôle. Le canvas, afin d'accélérer le rendu, maintient un ensemble de boîtes d'encadrement « sales » indiquant les zones de l'écran devant être redessinées – un bouton peut changer, par exemple, si la souris a juste été pressée à l'intérieur, impliquant son passage à l'état enfoncé. Durant ou avant le onPreRender, un contrôle peut appeler la méthode sur lui-même indiquant qu'il a besoin d'être redessiné. Puisque le moteur de Torque travaille avec un dispositif de basculement de pages et qu'il peut y avoir jusqu'à trois buffers séparés avec de vieilles données d'écran, le Canvas maintient trois rectangles « sales » représentant l'état de « saleté » de chacun des (jusqu'à) trois buffers. Après onPreRender, le Canvas effectue le rendu de la hiérarchie des contrôles en indiquant la racine de chaque couche (contrôle contenu) à onRender() lui-même, et en passant dans un rectangle de la zone visible de ce contrôle, qui est initialement positionné sur la zone « sale » de l'écran. Lorsqu'un contrôle est rendu, il peut optionnellement appeler renderChikdControls avec ce rectangle visible qui délimitera le rectangle aux limites de chacun de ses contrôles enfants, et s'il n'y a aucune zone visible, appellera onRender() sur l'enfant avec le rectangle délimité comme zone visible. 5.9.4 Le système GUI et la Console Le système GUI est conçu pour travailler étroitement avec le langage Console. La classe GuiControl a une variable d'instance appelée mConsoleVariable qui est le nom d'une variable de console globale qui sera, si , reflète l'état de ce contrôle d'une manière dépendante du contrôle. Par exemple, une variable qui est liée à un contrôle checkbox aura la valeur de 1 lorsque le contrôle est coché et 0 lorsqu'il ne l'est pas. Chaque GuiControl a également une variables d'instance appelée mConsoleCommand, et mAltConsoleCommand qui sont exécuté dans différents cas dépendant du contrôle – dans le cas d'un GuiButton, le script mConsoleCommand sera évalué lorsque le bouton est cliqué (dans GuiControl::onAction()). Une autre façon au système GUI d'interagir avec la console est via l'espace de nommage Console – lorsque vous nommez un contrôle (comme MainMenuQuitButton) ce nom de contrôle est enregistré dans un espace de nommage dont le parent est la classe du contrôle – dans le cas d'un bouton, la méthode console onAction des boutons sera appelée lorsque le bouton sera pressé. Les contrôles personnalisés peuvent être construits de cette manière pour exécuter plusieurs commandes différentes avec des arguments personnalisés. 5.10 L'interface graphique utilisateur (GUI) 5.10.1 Aperçu Torque a un système de rendu de monde 3D modulaire et extensible. Les sous-classes de GuiTSCtrl surcharge les méthodes GuiTSCtrl::processCameraQuery() et GuiTSCtrl::renderWorld() pour définir l'orientation de la caméra/FOV (Field Of View), et trace la scène 3D en utilisant les commandes de dessin d'OpenGL. GuiTSCtrl gère le paramétrage du point de vue, de la matrice de la vue-modèle et de la matrice de projection. La classe GameTSCtrl, de l'exemple de code de Torque, appelle les fonctions globales GameProcessCameraQuery() et GameRenderWorld(). GameProcessCameraQuery() retourne la caméra active de l'objet contrôle courant (l'objet dans la simulation que le joueur contrôle actuellement), puis GameRenderWorld() fait que l'objet SceneGraph est rendu dans le monde. 5.10.2 SceneGraph La bibliothèque SceneGraph (engine/sceneGraph) est, sur le client, responsable du parcours dans la scène du monde et de la détermination des objets qui doivent être rendus dans le monde en fonction de la position courante de la caméra, et sur le serveur, détermine quels objets doivent être envoyés à chaque client en fonction de la position de chaque client dans le monde. Le monde dans la SceneGraph est divisé en zones – volumes d'espace limité par des zones solides et des portails. Le monde extérieur est une zone unique, tandis que les objets intérieurs peuvent avoir de multiples zones internes. SceneGraph::findZone() trouve la zone d'un point 3D donné et rapporte le SceneObject auquel appartient cette zone. SceneGraph::rezoneObject() détermine quelles sont les zones contenant une instance SceneObject. Au moment du rendu, la scène est parcourue en commençant de la zone contenant la caméra, délimitant les objets de chaque zone au portail visible indiqué par les zones avant lui. L'analyse des objets réseau est effectuée dans SceneGraph::scopeScene(). 139 / 223 Documentation de Torque V1.3.x Le parcours du graphe de scène est compliqué par les portails de transformation. Les portails de transformation sont comme des miroirs ou des téléporteurs au travers desquels le monde peut être vu en utilisant une transformation différente de la transformation de caméra normale. Lorsque SceneGraph::buildSceneTree() rencontre un objet avec un portail de transformation, il construit un nouvel objet SceneState pour effectuer le rendu du contenu de ce portail. Chaque objet du monde pouvant être rendu dans la scène dérive de la classe de base SceneObject. Comme le monde est parcouru, les objets visibles sont sollicités pour préparer un ou plusieurs objets SceneRenderImage (dans SceneState::insertRenderImage()) qui sont ensuite insérés dans le SceneState courant via SceneObject::insertRenderImage(). Les images rendues sont triées en fonction de leur transparence et rendues avec SceneObject::renderObject(). Ce système permet, par exemple, à un objet interior avec de multiples fenêtres translucides d'effectuer le rendu du bâtiment en premier, suivi pas les autres objets, suivi par les fenêtres du bâtiment. Les objets peuvent insérer n'importe quel nombre d'images pour le rendu. 5.10.3 Terrain La bibliothèque Terrain (engine/terrain) est la racine pour les objets du rendu de l'extérieur du monde, incluant les instances des classes Sky, TerrainBlock et WaterBlock. L'objet Sky effectue le rendu extérieur des couches du ciel et des nuages, et maintient la distance de visibilité et la distance de brouillard paramétrées pour le monde. Le ciel s'occupe également des couches verticales de brouillard et les installe dans SceneGraph pour le rendu. TerrainBlock gère un simple bloc de 256x256 se répétant à l'infini d'altitude du terrain. La donnée d'altitude du terrain est stockée et chargée en utilisant la classe de ressource TerrainFile (Ressource<TerrainFile>) afin qu'un fichier unique de données de terrain puisse être partagé entre le serveur et le client, lorsque les deux sont sur l'exécution de la même instance. La classe statique TerrainRender est utilisée par les instances de TerrainBlock pour le rendu. La fonction TerrainRender::renderBlock() effectue le rendu de la répétition courante de blocs de terrain. Il existe une ressource TerrainManager qui vous permet d'avoir NxM répétitions de zones de terrain, augmentant la zone de non-répétition de terrain. Le terrain est texturé par logiciel en mélangeant les textures de matériaux de base dans de nouvelles textures de matériaux et ensuite en les plaquant via 16 ou plus carrés de terrain et en se basant sur la distance à partir du carré. Le mélangeur effectue le mélange des textures de terrain et inclut une version en assembleur MMX pour accélérer le traitement (architecture x86 uniquement). La classe WaterBlock gère un bloc unique d'eau qui peut ou ne peut pas se répéter infiniment. L'eau est détaillée dynamiquement basée sur la distance, ainsi l'eau proche est plus en mosaïque. Cependant, la surface d'un bloc d'eau est rectangulaire, l'étendue actuelle de la zone d'eau peut être initialisée à partir d'un point sur la surface, permettant à l'eau de remplir un cratère, par exemple, sans déborder des bords. 5.10.4 Interior La bibliothèque Interior (engine/interior) gère le rendu, les collisions et les E/S pour les objets interiors. La classe InteriorInstance de SceneObject gère un seul intérieur. La classe InteriorResource gère les données associées avec une définition d'intérieur, de multiples instances pouvant exister n'importe quand. Les Interiors gèrent des zones pour le graphe de scène, et peuvent avoir des sous-objets qui, par exemple, effectuent le rendu d'une vue miroir (MirrorSubObject). La classe InteriorLMManager gère les lightmaps pour tous les interriors actuellement chargés – partageant les lightmaps entre instances autant que possible. Les Interiors sont convertis en DIF par l'outil Map2DIF (autrefois appelé Morian). Les fichiers sources sont juste des fichiers .map du style Quake – listes de « brosses » physiques convexes définissant les zones solides de l'intérieur. Les brosses spéciales sont utilisées pour définir des limites de portails de zone et des objets tels que des portes ou des plates-formes. 5.10.5 3Space (TS) La bibliothèque 3Space (engine/ts) gère l'affichage et l'animation des modèles de forme dans le monde. La 140 / 223 Documentation de Torque V1.3.x classe TSShape de ressource de la forme 3Space peut être partagé entre de multiples instances TSShapeInstance. La classe TSShape gère toutes les données statiques d'une forme – données de maillage, trames clefs d'animation, listes des matériaux, informations de décalque, déclencheurs et niveaux de détail (pour les formes détaillées dynamiquement). La classe TSShapeInstance gère l'animation, le rendu et détaille la sélection pour une instance d'une forme. La classe TSShapeInstance utilise la classe TSThread pour gérer une des animations fonctionnant concurremment sur une instance. TSShapeInstance::addThread() initialise un nouveau thread sur une instance de forme, et TSShapeInstance::setSequence() paramètre une séquence d'animation pour un thread donné. Chaque thread peut être individuellement avancé dans le temps, ou peut être paramétré sur une échelle de temps qui est utilisée lorsque tous les threads sont avancés dans TSShapeInstance::advanceTime(). Un thread peut aussi gérer les transitions entre les séquences avec TSShapeInstance::transitionToSequence(). Les séquences d'animation TSShape peuvent être composées d'animations de noeuds/d'os (par exemple, articulations dans une explosion), animation de matériaux (une animation de texture sur une explosion) et une animation de maillage (un morphing24 de blob25 – notez que la plupart des animations de maillage peuvent être accomplies avec animations de changement d'échelle et des rotations de noeuds). Les animations peuvent aussi contenir des pistes de visibilité de sorte que certaines mailles de la forme ne sont pas visibles jusqu'à ce qu'une animation soit jouée. 5.11 Le réseau 5.11.1 Aperçu Torque a été conçu jusque dans ses fondations pour offrir des simulations avec réseau client/serveur. Les performances sur Internet ont dirigé la conception du modèle réseau. Torque tente de prendre en charge ceci avec trois problèmes fondamentaux de programmation de simulation réseau – bande passante limitée, perte de paquets et latence. Pour plus de détails sur la description de l'architecture réseau de Torque, bien que peut-être légèrement périmé, reportez-vous au document « The Tribes II Engine Networking Model » de Tim Gift et Mark Frohnmayer en complément de la présentation PowerPoint dans la partie documentation de Torque sur GarageGames.com. Une instance de Torque peut être désignée comme un serveur dédié, un client ou les deux à la fois. Si le jeu est un client ET un serveur, il se comporte toujours comme un client connecté à un serveur – au lieu d'utiliser le réseau, cependant, l'objet NetConnection a un lien de « court-circuit » vers un autre objet NetConnection dans la même instance de l'application. La bande passante est un problème, car l'environnement étendu et ouvert que Torque permet, et avec le grand nombre de clients que Torque supporte (jusqu'à 128 par serveur, ou plus si le réseau/serveur peut le gérer), beaucoup d'objets différents peuvent potentiellement être déplacés et mis à jour à la fois. Torque utilise trois stratégies principales pour maximiser la bande passante disponible. D'abord, il donne la priorité aux données, envoyant à une fréquence plus grande les mises à jour les plus « importantes » pour un client et, à une fréquence plus faible, les mises à jour moins importantes. En second lieu, il n'envoie que les données nécessaires – en utilisant la classe BitStream, seul le nombre minimum de bits nécessaires pour un morceau donné des données sera envoyé. En outre, lorsque l'état d'un objet change, Torque n'envoie que la partie modifiée de l'objet. Pour finir, Torque met en cache les chaînes (NetStringTable) et les données (SimDataBlock) communes de sorte qu'elles ne soient transmises qu'une seule fois. La perte de paquets est un problème, car l'information dans les paquets de données perdus doit, d'une manière ou d'une autre, être retransmise, pourtant dans beaucoup de cas, les données dans le paquet abandonné, ne seront plus fraîches le temps qu'elles arrivent au client – par exemple, supposons que le paquet 1 contienne la mise à jour de la position d'un joueur et que le paquet 2 contienne une position plus récente de ce même joueur. Si le paquet 1 est abandonné, mais que le paquet 2 passe correctement, le 24 Le morphing ou morphage est un des effets spéciaux applicables à un dessin vectoriel ou bitmap. Il consiste à fabriquer une animation qui transforme de la façon la plus naturelle et la plus fluide possible un dessin initial vers un dessin final. Il est la plupart du temps utilisé pour transformer un visage en un autre. (Wikipédia) 25 Objet tridimensionnel utilisé en imagerie de synthèse et obtenu par la déformation mutuelle de sphères s'attirant ou se repoussant. En fait, c'est complètement impossible à décrire, et même à imaginer quand on cherche à en créer un. 141 / 223 Documentation de Torque V1.3.x moteur ne devrait pas renvoyer les données qui étaient dans le paquet 1 – il est plus vieux que la version qui a été reçue par le client. Afin de réduire au minimum le renvoi inutile de données, le moteur classe les données en quatre groupes : • • • • Donnée non garantie (NetEvent) – si cette donnée est perdue, ne pas la retransmettre. Un exemple de ce type de donnée pourrait être la transmission en temps-réel de la voie – avant qu'il ne soit retransmis, les segments de voie suivants auront déjà été joués. Donnée garantie (NetEvent) – si cette donnée est perdue, la retransmettre. Les messages de discussion (Chat), les messages d'arrivée et de départ de joueurs dans le jeu, et les messages de fin de mission sont des exemples de données garanties. Donnée d'état plus récent (NetObject) – seule la version la plus courante de la donnée est importante – si une mise à jour est perdue, on envoie l'état courant, à moins qu'il ait été déjà envoyé. Donnée la plus rapide garantie (Move) – donnée critique qui doit être obtenue dès que possible. La latence est un problème dans la simulation, car le retard dans le transfert de l'information par le réseau (qui, pour les modems, peut être d'un quart de seconde ou plus) rend la vue du client du monde perpétuellement désynchronisée avec le serveur. Les jeux de mouvement de type FPS, pour lesquels Torque avait été initialement conçu, exigent une réponse instantanée de contrôle afin de ressentir n'importe quoi, mais lentement. Aussi, les objets à déplacement rapide peuvent être difficiles à gérer pour les joueurs à fort niveau de latence. Afin de résoudre ces problèmes, Torque emploie plusieurs stratégies : • • • L'interpolation est utilisée pour déplacer sans à-coups un objet de l'endroit où le client pense qu'il est vers l'endroit où le serveur dit qu'il est. L'extrapolation est utilisée pour deviner où va l'objet, en se basant sur son état et ses règles de mouvement. La prédiction est utilisée pour former une divination par apprentissage sur l'endroit où va un objet, en se basant sur règles de mouvement et les entrées du client. L'architecture réseau est en couche : en bas, on a la couche plate-forme, au-dessus c'est la couche du protocole de notification, suivi par la couche de gestion des objets et événements NetConnection. La section suivante explique comment chaque couche s'adresse à certains ou tous les problèmes réseau fondamentaux de simulation. 5.11.2 Couche de gestion de réseau de plate-forme La bibliothèque de plate-forme fournit l'interface entre le moteur de jeu et les fonctionnalités réseau dépendantes de l'OS. L'interface Net de la bibliothèque de plate-forme contient les fonctions pour l'ouverture de sockets26 de communication fiable et peu fiable, la conversion des adresses réseau entre chaîne et numérique, et l'envoi et la réception des données. • • • • • • Net::openPort() ouvre un socket peu fiable, dont une seule est autorisée par instance d'application. Net::sendto() envoie un datagramme (ou paquet) peu fiable vers la NetAddress spécifiée. Net::openListenPort() ouvre un socket fiable pour les connexions TCP entrantes. Net::openConnectTo() lance le processus de connexion asynchrone sur un socket TCP distant. Net::sendtoSocket() envoie des données au travers d'une connexion TCP établie. Net::process() traite la couche réseau plate-forme, en générant les événements relatifs au réseau qui sont alors postés dans la simulation via GameInterface::processEvent(). Torque a également une bonne capacité au débogage. Les macros DEBUG_NET() et DEBUG_LOG() sont utilisées pour contrôler les sorties de débogage à partir du code de réseau. Une explication complète de cette fonctionnalité est en dehors du cadre de cet aperçu; cependant, la recherche des sources des instances de DEBUG_LOG() devrait vous mettre sur le chemin de la compréhension de cette partie de Torque. 26 Apparu dans les systèmes UNIX, un socket est un élément logiciel qui est aujourd'hui répandu dans la plupart des systèmes d'exploitation. Il s'agit d'une interface logicielle avec les services de ce dernier, grâce à laquelle un développeur exploitera facilement et de manière uniforme les services d'un protocole réseau. (Wikipédia) 142 / 223 Documentation de Torque V1.3.x 5.11.3 Protocole de connexion 5.11.3.1 Négociation de la connexion La négociation d'une connexion réseau d'un jeu n'est pas actuellement une partie de l'arbre des classes réseau dans Torque – au lieu de cela, un ensemble de fonctions, déclarées dans engine/game/netDispatch.cc assure ce service. La fonction DemoGame::processPacketReceiveEvent() est la fonction de distribution des paquets réseau entrants. La première étape du processus de connexion est la fonction console connect() qui initie une tentative de connexion en envoyant un paquet de demande de négociation de connexion vers le serveur à partir de sendConnectChallengeRequest(). Le serveur, dans handleConnectChallengeRequest(), peut demander au client, une réponse à la demande de négociation de connexion, que le client traitera dans handleConnectChallengeResponse. Le client émettra en retour une demande de connexion (sendConnectRequet) avec les informations de négociation qu'il a reçues du serveur. Le serveur traite ce message dans handleConnectRequest. Si le serveur décide d'accepter la demande, il renvoie au client un sendConnectAccept et construit un objet NetConnection sur le serveur pour identifier ce client. Le client, dans handleConnectAccept, crée un objet complémentaire NetConnection pour gérer le côté client de la connexion. La fonction dispatchCheckTimeouts teste régulièrement si une demande de connexion a attendu trop longtemps et révise la demande si nécessaire. 5.11.3.2 Une fois que nous sommes connectés... Une fois qu'une connexion a été établie, la fonction de la classe ConnectionProtocol est de fournir un mécanisme commun de bas niveau pour le support des quatre types fondamentaux de données de réseau dans Torque. La classe de base d'abstraction ConnectionProtocol implémente un flux de message sur un transport peu fiable (UDP). Plutôt que de supporter directement des messages garantis, la classe ConnectionProtocol implémente un protocole de notification. Chaque paquet envoyé est précédé d'un en-tête de message contenant des informations de suivi, incluant quels sont les paquets que le destinataire a reçus, ou ceux perdus en cours de route. Lorsqu'une instance ConnectionProtocol détermine qu'un paquet a bien été reçu ou a été perdu, il appelle ConnectionProtocol::handleNotify(). Les notifications sont toujours délivrées dans l'ordre d'envoi des paquets – ainsi, pour tout paquet envoyé via un objet ConnectionProtocol, éventuellement une notification de succès (ack) ou d'insuccès (nack) sera exécutée. Puisque le protocole de réseau de base exporte la nature peu fiable inhérente du réseau vers la simulation, à un haut niveau, Torque peu directement supporter différents types de garanties de données : pour les données non garanties, si elles ne sont pas délivrées correctement («nack»ed), il n'y a pas besoin de les réenvoyer. Pour les données garanties, si elles ne sont pas délivrées correctement, le moteur est sollicité pour les envoyer à nouveau (NetConnection::ghostPacketDropped()). Si la donnée doit être délivrée le plus rapidement possible, elle est envoyée avec chaque paquet jusqu'à ce qu'un paquet contenant la donnée soit notifiée avec succès (acked) (GameConnection::readPacket()). 5.11.3.3 NetConnection La classe NetConnection est dérivée à la fois de SimGroup et ConnectionProtocol, et responsable de la gestion de la circulation des données entre le client et le serveur. La classe NetEvent encapsule les types de délivrance garantie et non garantie des messages, et la portion de gestion dupliquée de la classe NetConnection manipule des mises à jour des états des objets du monde du serveur vers le client. La sous-classe de NetConnection de l'exemple de jeu de Torque est GameConnection et gère la transmission des données spécifiques du jeu tels les déplacements de joueurs. La classe NetConnection envoie des paquets de taille fixe dans un flux régulier entre le client et le serveur. Lorsqu'un message est posté pour transmission, il est agrégé avec d'autres messages et envoyé suivant le débit et taille de paquet paramétrés pour cette connexion. 5.11.3.4 BitStream BitStream est une classe utile utilisée pour empaqueter les données pour transmission. BitStream a des méthodes pour la lecture et l'écriture de variables entières ou flottantes, de vecteurs, de chaînes codées de 143 / 223 Documentation de Torque V1.3.x Huffman et de bits. Lorsqu'une instance NetConnection détermine qu'elle est prête à envoyer un paquet sur le réseau (NetConnection::checkPacketSend()), elle alloue un BitStream est appelle NetConnection::writePacket() avec le flux. Lorsqu'un paquet est reçu, il est traité via la fonction NetConnection::readPacket(). 5.11.3.5 Événements réseau (NetEvent) La classe NetEvent fournit les fondations pour la transmission de messages garantis, garantis ordonnés et non garantis. NetEvent utilise le même mécanisme de création de classe que la console, mais plutôt que d'instancier par le nom, NetEvents utilise une ID de classe, qui a été assignée lors de l'initialisation de la console. Si les méthodes de compression et de décompression ne fonctionnent pas en terme de lecture et d'écriture dans le flux, de graves erreurs réseau peuvent survenir. Le client et le serveur doivent se déconnecter proprement dans ces cas, mais les erreurs elles-mêmes peuvent être très difficiles à traquer. Si la macro DEBUG_NET est définie, une clef spéciale sera inscrite dans le paquet après chaque événement et mise à jour d'objet, et le système protestera immédiatement lorsqu'il détecte que ce problème survient. 5.11.3.6 Contexte et réplication réseau La classe NetObject est dérivée de SimObject qui peut se répliquer (ghost) elle-même au travers de la connexion réseau. Toutes les classes d'objets sont des sous-classes de NetObject (la superclasse de SceneObject). Afin d'utiliser au mieux la bande passante disponible, NetConnection tente de déterminer quels sont les objets « intéressants » chaque client – et parmi ces objets, quels sont les plus importants. Si un objet intéressant pour un client, on dit qu'il est dans le « contexte » (scope) – par exemple, un ennemi visible à un joueur en mode première personne devra être dans le contexte. Chaque objet NetConnection maintient un objet de contexte – chargé de la déterminer quels objets sont dans le contexte pour ce client. Avant que NetConnection n'inscrive une information répliquée de mise à jour dans chaque paquet dans NetConnection::ghostWritePacket(), il appelle la fonction onCameraScopeQuery() d'objet de contexte qui assure deux services : premièrement, il détermine quels objets sont dans le contexte pour ce client et appelle NetConnection::objectInScope pour chaque objet de ce client. Deuxièmement, l'appel à onCameraScopeQuery() emplit la structure CameraScopeQuery qui est alors utilisée pour déterminer la priorité des mises à jour des objets. La fonction par défaut NetObject::onCameraScopeQuery repère tout dans le monde, mais l'ex'mple de jeu Torque surcharge ceci dans ShapeBase::onCameraScopeQuery(). ShapeBase appelle la fonction serveur SceneGraph::scopeScene() pour parcourir la scène à partir du point de vue du client et repérer tous les objets potentiellement visibles. Chaque objet repéré nécessitant d'être mis à jour se voit alors affecter une priorité basée sur la valeur de retour de la fonction NetObject::getUpdatePriority(), qui retourne par défaut une valeur constante. Cette fonction est surchargée dans ShapeBase::getUpdatePriority() pour prendre en compte la distance entre la caméra et les objets, sa vélocité par rapport au vecteur de vue, et d'autres facteurs. Plutôt que de toujours envoyer l'état complet d'un objet sur le réseau, à chaque fois qu'il est mis à jour, Torque supporte l'envoi seul des portions qui ont été modifiées. Pour faciliter ceci, chaque NetObject peut spécifier jusqu'à 32 sous-états indépendants qui peuvent être individuellement modifiés. Par exemple, un objet de joueur peut avoir un état de mouvement, détaillant sa position et sa vitesse, un état de dommage, détaillant son niveau de dommage et les zones touchées, et un état d'animation, signifiant quelle animation, s'il y en a, le joueur effectue. À chaque groupe de données d'état est assigné un bit de position dans la classe. Lorsqu'un état d'objet survient, l'objet le notifie sur le réseau avec la fonction NetObject::setMaskBits. Quand l'objet doit être écrit dans un paquet, le masque d'état courant de l'objet est passé à NetObject::packUpdate. Le masque d'état de l'objet n'est PAS directement écrit dans le paquet – c'est à la charge de la fonction d'empaquetage de coder exactement quels états sont mis à jour. Au début, un masque d'état d'objet à tous les bits à 1. 144 / 223 Documentation de Torque V1.3.x 5.11.3.7 Objet GameConnection, déplacements et contrôle GameConnection est la sous-classe spécifique au jeu de NetConnection. Les applications peuvent sousclasser NetConnection pour lire et écrire des données directement dans le mécanisme de notification. La fonction NetConnection::allocNotify() est appelée au début de l'écriture d'un paquet et est utilisée pour allouer une structure NetConnection::PacketNotify(). Cette structure est utilisée pour stocker des informations sur les données écrites dans le paquet réseau. Quand le paquet est notifié en succès (acked) ou en échec (nacked), cette structure de notification est passée à la fonction NetConnection::handleNotify(). Les sous-classes de NetConnection peuvent sous-classer la structure PacketNotify et surcharger la méthode allocNotify pour ajouter des données personnalisées à l'enregistrement de suivi de paquet. Le GameConnection dans l'exemple de Torque introduit le concept de l'objet de contrôle. L'objet de contrôle est simplement l'objet que le client associe avec ce contrôle de connexion réseau. Par défaut, dans l'exemple, l'objet de contrôle est une instance de la classe Player, mais peut aussi être une instance de Camera (lors de l'édition de la mission, par exemple). L'exemple de Torque utilise un modèle dans lequel le serveur est le maître officiel de la simulation. Pour empêcher les clients de tricher, le serveur simule tous les déplacements des joueurs et indique au client où son joueur est situé dans le monde. Ce modèle, bien que sécurisé, peut avoir des problèmes – si la latence réseau est importante, cette durée d''aller-retour peut donner au joueur un sentiment très prononcé de retard des mouvements. Pour remédier à ce problème, l'exemple utilise une forme de prédiction – il simule le mouvement de l'objet à la fois côté serveur et côté client. Ainsi, le client n'a pas besoin d'attendre la vérification aller-retour pour ses déplacements – seulement dans le cas d'une action forcée sur l'objet côté serveur qui n'existe pas sur le client fait que la position du client a besoin d'être changée de manière forcée. Pour effectuer ceci, tous les objets de contrôle (dérivés de ShapeBase) doivent fournir les fonctions writePacketData() et readPacketData() qui envoient assez de données pour simuler exactement l'objet sur le client. Ces fonctions sont appelées seulement pour l'objet de contrôle courant, et seulement lorsque le serveur peut déterminer que la simulation du client est d'une manière ou d'une autre désynchronisée avec le serveur. Ceci arrive habituellement si le client est affecté par une force non présente sur le serveur (comme un objet interpolé) ou si l'objet serveur est affecté par une force serveur seule (telle que l'impulsion d'une explosion). La structure Move est un instantané du joueur de 32 millisecondes, contenant les modifications de position x, y et z, et de rotation aussi bien qu'une modification d'état de déclenchement (trigger). Lors du déroulement du temps dans la simulation, les déplacements sont collectés (dépendant de la longueur du temps passé), et appliqués à l'objet de contrôle courant sur le client. Les mêmes déplacements sont alors empaquetés vers le serveur dans GameConnection::writePacket(), pour le traitement sur la version serveur de l'objet de contrôle. 5.11.3.8 Datablocks Les Datablocks (c'est-à-dire, sous-classes de SimDataBlock) sont utilisés dans le système réseau pour stocker les données communes d'instance pour les objets. Par exemple, un datablock peut stocker des données d'animation, des informations de modèle, des propriétés de mouvement physique, etc., tout ce qui est partagé au travers d'un jeu d'objets communs. Tous les datablocks déclarés sont envoyés sur la connexion comme événements garantis (SimDataBlockEvent), et peuvent alors être référencés et envoyés comme partie de ma mise à jour initiale dupliquée (ghost). Un avantage des datablocks est qu'ils ne sont déclarés que sur le serveur, ainsi des mods pour le jeu peuvent être créés sans obliger le client à télécharger des données de script. 5.11.3.9 NetStringTable La classe NetStringTable gère les données de chaînes au travers des connexions. Chaque chaîne marquée (tagged) dans la console – celles encadrées par une apostrophe (') seront envoyées sur une connexion qu'une seule fois. Chaque fois suivante qu'une chaîne est envoyée, un marqueur entier est substitué à l'actuelle donnée de chaîne. Les chaînes, comme les noms des joueurs, peuvent être ajoutées avec la fonction console addTaggedString et supprimées avec la fonction console removeTaggedString. 145 / 223 Documentation de Torque V1.3.x 5.11.3.10 Commandes de console réseau Il y a deux procédures distantes appelées commandes de console réseau – commandToServer et commandToClient. La fonction commandToServer prend la forme : commandToServer(fonctionNameTag, arg1, arg2, arg3, ...), où fonctionNameTag est un marqueur de chaîne. Cet appel est converti en RemoteCommandEvent et initialisé au travers du serveur. Une fois ici, le serveur appelle la fonction de script local serverCmdXXX(clientId, arg1, arg2, arg3, ...), où XXX est le texte de la chaîne marquée. La fonction commandToClient prend la forme : commandToCLient(clientId, fonctionNameTag, arg1, arg2, arg3,...) où l'argument clientId est l'identifiant de l'objet connexion à envoyer. Les fonctions commandTo... assure la substitution automatique d'arguments de chaîne en utilisant le modificateur de format %. Par exemple : commandToClient('EchoMessage', 'This %1 guy is super %2', 'Got Milk?', 'slow at writing documentation'); est exécuté sur le client ainsi : function clientCmdEchoMessage(%message, %a1, %a2, %a3, %a4) { // les chaînes marquées doivent être « démarquées »afin d'être affichées echo(detag(%message)); echo("a1 = " @ detag(%a1)); echo("a2 = " @ detag(%a2)); echo("a3 = " @ detag(%a3)); echo("a4 = " @ detag(%a4)); } et devrait afficher : This Got Milk? guy is super slow at writing documentation a1 = Got Milk? a2 = slow at writing documentation a3 = a4 = Le numéro de substitution de chaîne (après le %) fait référence à la position n de l'argument, après l'argument courant : commandToClient('EchoMessage', '%1 is a good %2 for %3', '%1 the good %2', 'Role Model', 'SuperDood %1', 'the dude of super'); devrait afficher : Role Model the good SuperDood the dude of super is a good Role Model for SuperDood the dude of super A1 = Role Model the good SuperDood the dude of super A2 = Role Model A3 = SuperDood the dude of super A4 = the dude of super Cette fonctionnalité est spécialement utile pour les messages d'état et de jeu à partir du serveur, car chaque message de texte est compressé juste dans un petit tableau d'identificateurs de marqueur. 146 / 223 Documentation de Torque V1.3.x Annexe A : Création du Torque Game Engine A.1 Aperçu Lorsque vous possédez une licence Torque, vous pouvez accéder à tout le code source du moteur et du SDK. Ainsi, la première étape pour obtenir et faire fonctionner le moteur est d'obtenir le code source et de le compiler. Ce chapitre vous mènera tout au long du processus, avec des guides pour Windows, Mac OS X et Linux. Avant d'entrer plus dans les détails, jetons un coup d'œil rapide aux directives que vous suivrez, en fonction de votre plate-forme. Premièrement, vous téléchargerez le code source du SDK de Torque. GarageGames utilise un système d'installation de code source afin d'accéder aux dernières mises à jour du moteur. La communauté Torque est très active, et améliore et teste le Torque Game Engine SDK régulièrement. L'utilisation de l'installateur vous permet très facilement d'être à jour, vous pouvez toujours télécharger la dernière version du moteur à partir de votre page d'accueil GarageGames. Comme pour la compilation, GarageGames fournit un certain nombre d'options. La compilation est assez simple, en utilisant les compilateurs que supporte officiellement GarageGames. Dans ce guide, vous trouverez les marches à suivre pour compiler Torque avec GCC3, Xcode, et Microsoft Visual C++ version 6.0, .NET 2003 (7.0), et .NET 2003 (7.1). Le reste de ce chapitre consiste en des guides spécifiques à chaque plate-forme en compilant le code source du SDK pour Windows, Mac et Linux. Prenez le guide correspondant à votre plate-forme. A.2 Création de Torque pour Windows A.2.1 Préparation de votre système Vous n'avez pas grand-chose à faire pour que votre système soit prêt pour fonctionner avec Torque. Sur Windows, assurez-vous simplement d'avoir les prérequis système suivants : Mettez à jour les pilotes vidéo ! Le TGE utilise OpenGL pour son rendu. Le support OpenGL est inclus dans les pilotes des cartes vidéos, qui sont fournis par les fabricants de cartes vidéo et sont en constante mise à jour. La plupart des fabricants ont un site Internet avec des instructions simples de téléchargement de pilotes. L'assurance d'avoir les derniers pilotes est critique pour le fonctionnement de Torque. Matériels requis : • • • Pentium I, II, III, IV, AMD Athlon, 64, etc. 64 Mo de RAM ou plus, très dépendant de votre application. Carte vidéo avec accélération 3D matérielle telle que les cartes du style AGP Radeon ou GeForce. Logiciels requis : • • • • Windows 98, Windows NT avec SP6, Windows 2000 avec SP4, Windows XP avec SP1, ou supérieur. Rappelez-vous : ayez toujours les derniers pilotes pour votre carte vidéo. DirectX version 8.0 ou supérieure. OpenAL runtime ou installation du SDK. Outils de développement : • • Visual C++ 6.0, 7.0, ou 7.1. Les GCC et autres compilateurs gratuits fonctionneront également, mais GarageGames ne les supporte pas officiellement. Il est également recommandé que vous téléchargiez quelques outils tels que JEdit (et le TorqueIDE pour Jedit), WinGrep (pour effectuer facilement des recherches de texte) et WinMerge (pour 147 / 223 Documentation de Torque V1.3.x fusionner du code de base séparé, si nécessaire) En résumé : Note : bien que le moteur ait des exigences assez minimales jusque dans le matériel, les performances de n'importe quel jeu créé en utilisant le TGE déprendront considérablement de la manière dont chaque jeu se sert des ressources disponibles. Les jeux TGE peuvent être de n'importe quel type, allant d'un petit jeu 2D très peu gourmand jusqu'au summum d'un jeu de rôle 3D, d'un FPS, d'une course, ou d'un simulateur de vol, et tout ce que vous pourrez rêver ! Torque est un moteur à hautes performances, il ne tient qu'à vous d'en tirer bénéfice. Maintenant que vous avez téléchargé le code source, et que votre système est prêt, lisez la suite pour apprendre comment compiler le code pour Windows. A.2.2 Compilation du Torque Game Engine SDK avec le Microsoft Visual C++ .NET 2003 (7.1) Abstraction Ce guide explique le processus de création des projets dans le TGE utilisant le Microsoft Visual C++ .NET 2003 (7.1). Note : ce guide est destiné aux développeurs utilisant le Visual C++ .NET version 2003 (également appelée version 7.1). Si vous avez la version 2002 (également appelée version 7.0), votre procédure de création est très différente. Reportez-vous à la section concernée. Étape 1 : Installation La création du TGE (TGE) avec le Visual C++ 7.1 est un processus simple. Vous devez déjà avoir la version stable la plus récente du TGE téléchargée sur votre système. Si cela n'est pas le cas, allez sur votre page My Account page et suivez les liens de téléchargement. Vous devez aussi avoir les logiciels de base requis par le TGE installés et configurés sur votre machine. Ceci inclut les logiciels système, les extensions et les pilotes. Veuillez vous référer à la section sur la préparation de votre système. Si vous ne l'avez pas déjà fait, vous devez aussi installer votre copie de Visual C++ 7.1. Suivez les instructions d'installation fournies avec. Le processus d'installation diffère légèrement si vous avez une édition standard, professionnelle, entreprise ou autre de VC++ 7.1. Vous n'avez rien à faire de spécial lors de l'installation ; Torque sera compilé avec les composants par défaut du VC++ 7.1. Étape 2 : Configuration de Visual C++ 7.1. Une configuration rapide est nécessaire afin de fonctionner avec le TGE dans VC++. Le TGE utilise l'extension de fichier .cc pour tous ses fichiers sources C++. Malheureusement, Visual C++ ne reconnaît pas automatiquement l'extension de fichier .cc, vous devez donc en ajouter le support. Nous fournissons un fichier, appelé « VC7 .cc compiling.reg », qui modifiera la base de registres de Windows pour ajouter le support de .cc à Visual C++. Pour exécuter ce fichier, ouvrez le répertoire dans lequel vous avez installé Torque, par exemple « C:\Torque », et allez dans le sous-répertoire « vc7 ». Double-cliquez sur le fichier « VC7 .cc compiling.reg » pour le lancer. Une boîte de dialogue vous demandera de confirmer la modification des registres : 148 / 223 Documentation de Torque V1.3.x Cliquez sur le bouton « Yes ». Votre copie de VC++ 7.1 est maintenant prête pour fonctionner avec le TGE. Étape 3 : Création de la Torque Demo Une fois encore, ouvrez le répertoire où est installé Torque et allez dans le sous-répertoire « vc7 ». Double-cliquez sur le fichier « Torque SDK.sln » pour ouvrir le fichier VC++. Ceci est le fichier de base pour le Torque SDK, et c'est à partir de ce fichier que nous pouvons créer la Torque Demo. Dans le Visual C++ Solution Explorer, cliquez l'élément « Torque Demo ». Maintenant, cliquez sur le menu « Build », et sélectionnez la commande « Build Torque Demo ». Visual C++ commencera la création de l'application torqueDemo.exe. Vous pouvez voir le résultat de ceci dans la fenêtre Output de VC++. 149 / 223 Documentation de Torque V1.3.x Ceci peut prendre plusieurs minutes pour s'effectuer, mais vous obtiendrez une copie fonctionnelle du fichier « torqueDemo.exe » dans le sous-répertoire « example » de votre répertoire Torque. Félicitations, vous avez créé avec succès la Torque Demo, et votre système est prêt pour fonctionner avec les sources Torque dans le VC++ 7.1 ! A.2.3 Compilation du Torque Game Engine SDK avec le Microsoft Visual C++ .NET 2002 (7.0) Abstraction Ce guide explique le processus de création des projets dans le TGE utilisant le Microsoft Visual C++ .NET 2002 (7.0). Note : ce guide est destiné aux développeurs utilisant le Visual C++ .NET version 2002 (7.0). Si vous avez la version 2003 (également appelée version 7.1), votre procédure de création est très différente. Reportez-vous à la section concernée. Étape 1 : Installation La création du TGE (TGE) avec le Visual C++ 7.0 est un processus simple. D'abord, notez que les instructions de création proposées ici ne sont pas aussi détaillées que les autres versions de VC++. VC++ 7.0 est, en général, plus difficile pour travailler que les autres versions de ce produit. Avant de commencer ce guide, vous devez déjà avoir la version stable la plus récente du TGE téléchargée sur votre système. Si cela n'est pas le cas, allez sur votre page My Account page et suivez les liens de téléchargement. Vous devez aussi avoir les logiciels de base requis par le TGE installés et configurés sur votre machine. Ceci inclut les logiciels système, les extensions et les pilotes. Veuillez vous référer à la section sur la préparation de votre système. Si vous ne l'avez pas déjà fait, vous devez aussi installer votre copie de Visual C++ 7.1. Suivez les instructions d'installation fournies avec. Le processus d'installation diffère légèrement si vous avez une édition standard, professionnelle, entreprise ou autre de VC++ 7.1. Vous n'avez rien à faire de spécial lors de l'installation ; Torque sera compilé avec les composants par défaut du VC++ 7.1. Étape 2 : Configuration de Visual C++ 7.0. Quatre configurations supplémentaires sont nécessaires afin de profiter de TGE avec le VC++ 7.0. Configuration étape 1) Installation de Microsoft .NET Framework 1.0 Service Pack 2 Avant de commencer à travailler avec Visual C++ .NET 2002, vous devrez télécharger et installer le dernier service pack du .NET Framework 1.0 directement à partir de Microsoft. Allez sur la page de mise à jour de Visual Studio de Microsoft, cherchez le .NET Framework 1.0 service pack, téléchargez le et suivez les instructions d'installation. Configuration étape 2) Ajout du support des fichiers .cc 150 / 223 Documentation de Torque V1.3.x Le TGE utilise l'extension de fichier .cc pour tous ses fichiers sources C++. Malheureusement, Visual C++ ne reconnaît pas automatiquement l'extension de fichier .cc, vous devez donc en ajouter le support. Nous fournissons un fichier, appelé « VC7 .cc compiling.reg », qui modifiera la base de registres de Windows pour ajouter le support de .cc à Visual C++. Pour exécuter ce fichier, ouvrez le répertoire dans lequel vous avez installé Torque, par exemple « C:\Torque », et allez dans le sous-répertoire « vc7 ». Double-cliquez sur le fichier « VC7 .cc compiling.reg » pour le lancer. Une boîte de dialogue vous demandera de confirmer la modification des registres : Cliquez sur le bouton « Yes ». Configuration étape 3) Conversion des fichiers du projet en VC++ 7.0 Les fichiers VC++ .NET inclus dans le TGE sont configurés pour VC++ .NET 2003 (version 7.1). Malheureusement, Microsoft n'a pas conçu les fichiers 7.1 compatibles avec VC++ 7.0. Ce problème doit être contourné. Une solution consiste à convertir les fichiers du projet VC++ 6.0 de Torque en VC++ 7.0. La procédure pour effectuer cela est décrite ci-après. Ouvrez le répertoire dans lequel Torque est installé. Ensuite, ouvrez le sous-répertoire « v6 ». Vous devrez convertir chaque fichier de Visual Studio 6.0 au format Visual Studio 7.0. Pour effectuer ceci, double-cliquez sur le fichier « Torque SDK.dsw ». Notez qu'une fois que les fichiers auront été convertis, ils ne seront plus lisibles par Visual C++ 6.0. Visual Studio 7.0 s'ouvrira et vous demandera si vous souhaitez convertir chaque fichier. Suivez les boîtes de dialogue qui apparaissent, et validez la conversion de chaque fichier. Maintenant, les fichiers devraient se charger correctement dans votre copie de VC++. Configuration étape 4) Paramétrer le répertoire de travail Malheureusement, VC++ 7.0 ne conserve pas correctement le répertoire de travail du projet lors de la conversion à partir des fichiers de projet de la version 6.0. Afin de créer et d'exécuter correctement la Torque Demo, ceci doit être corrigé. Pour cela, ouvrez la boîte de dialogue « Properties » du projet Demo Torque. Sélectionnez l'élément « Debugging » de la liste « Configuration Properties » sur la gauche. Sous la section « Action », saisissez dans le champ « Working Directory » la valeur suivante : ..\example VC++ 7.0 devrait maintenant être correctement configuré pour fonctionner avec le TGE. Étape 3 : Création de Torque Demo Pour créer la Torque Demo, cliquez sur l'élément « Torque Demo » dans l'explorateur de solution, et créer-la de manière habituelle. Le fichier « torqueDemo_DEBUG.exe » devrait être placé dans le sous-répertoire exemple de votre répertoire Torque. Vous avez créé maintenant la Torque Demo. Note : Visual C++ 7.0 est plus difficile à supporter que les autres versions de ce produit. Veuillez nous excuser pour le peu de détails de ce guide. Si vous désirez contribuer par des instructions complémentaires 151 / 223 Documentation de Torque V1.3.x ou des copies d'écran, envoyez un email à [email protected] avec un sujet approprié. A.2.4 Compilation du Torque Game Engine SDK avec le Microsoft Visual C++ 6.0 Abstraction Ce guide explique le processus de création des projets dans le TGE utilisant le Microsoft Visual C++ .6.0. Étape 1 : Installation Vous devriez déjà avoir tous les logiciels nécessaires installés et configurés. Ceci inclut les logiciels système, les extensions et les pilotes. Veuillez vous référer à la section sur les prérequis de TGE pour plus de détails. L'installation, la configuration et la création avec le Visual C++ 6.0 sont un simple processus en quatre étapes. Si vous avez déjà installé le Visual C++ sur votre ordinateur, veuillez revoir chaque étape avec attention, spécialement l'étape 3 pour être certain que votre ordinateur est correctement configuré. Le TGE a été testé pour être compatible avec Visual C++ Standard Edition, Visual C++ Professional Edition et Visual C++ Enterprise Edition. Lorsque vous être prêt à installer, insérez le CD-Rom et procédez à partir du dialogue « Common Install Folder ». Nous supposons que vous installez Visual C++ dans le répertoire recommandé par défaut « C:\Program Files\Microsoft\Visual Studio\Common ». Procédez avec la boîte « Installation Dialog » et installez dans le répertoire par défaut « C:\Program Files\Microsoft\Visual Studio\VC98 ». Cliquez sur le bouton « Typical Install » pour continuer. 152 / 223 Documentation de Torque V1.3.x Procédez ensuite avec la boîte « Setup Environment ». Assurez-vous que la case 'Register Environment Variables' est cochée. L'enregistrement des variables d'environnement est nécessaire pour que les outils en ligne de commandes et que vos fichiers makefile fonctionnent correctement. Cliquez sur OK pour continuer. Félicitations, vous avez installé le VC++ 6.0. Passez à la section suivante pour le téléchargement et l'installation du Service Pack 5 de VC++ 6.0. Étape 2 : Installation du Service Pack 5 pour Visual C++ 6.0 Micorosoft a fourni plusieurs mises à jour et corrections de bogue pour Visual C++ 6.0 depuis sa première sortie. Le Service Pack 5 est une collection cumulée de tous les Service Pack (SP4, SP3, SP2 et SP1) et inclus les correctifs. Pour en savoir plus sur le sujet et télécharger le Service Pack 5, allez sur la page de téléchargement de Microsoft. Suivez les instructions indiquées sur la page pour commencer le téléchargement. Le fichier est important, 133 Mo. La page de téléchargement présente les instructions complètes ; vous aurez beaucoup de temps pour les lire durant le téléchargement du Service Pack. Lorsque le téléchargement est fini, suivez les instructions et installez le Service Pack. Étape 3 : Configuration du Visual C++ 6.0 Une configuration rapide est nécessaire afin de fonctionner avec le TGE dans VC++. Le TGE utilise l'extension de fichier .cc pour tous ses fichiers sources C++. Malheureusement, Visual C++ ne reconnaît pas automatiquement l'extension de fichier .cc, vous devez donc en ajouter le support. Nous fournissons un fichier, appelé « VC6 .cc compiling.reg », qui modifiera la base de registres de Windows 153 / 223 Documentation de Torque V1.3.x pour ajouter le support de .cc à Visual C++. Pour exécuter ce fichier, ouvrez le répertoire dans lequel vous avez installé Torque, par exemple « C:\Torque », et allez dans le sous-répertoire « vc6 ». Double-cliquez sur le fichier « VC6 .cc compiling.reg » pour le lancer. Une boîte de dialogue vous demandera de confirmer la modification des registres : Cliquez sur le bouton « Yes ». Votre copie de VC++ 6 est maintenant prête pour fonctionner avec le TGE. Étape 4 : Création avec le Projects Files Une fois encore, ouvrez le répertoire où est installé Torque et allez dans le sous-répertoire « vc6 ». Double-cliquez sur le fichier « Torque SDK.sln » pour ouvrir le fichier VC++. Ceci est le fichier de base pour le Torque SDK, et c'est à partir de ce fichier que nous pouvons créer la Torque Demo. Maintenant que le fichier de projet est ouvert, nous pouvons créer l'application Torque Test en allant dans le menu « Buid » et en sélectionnant « Build torqueDemo_DEBUG.exe ». Vous pouvez aussi créer la démo avec le raccourci clavier F7. L'application peut prendre plusieurs minutes pour compiler dépendant de la rapidité de votre ordinateur et de la quantité de mémoire libre. Pour chaque fichier compilé, il sera indiqué dans la fenêtre « output ». Soyez patient. Vous pouvez regarder les résultats de la création dans la fenêtre « output » de VC++. Ceci peut prendre quelques minutes pour s'accomplir, mais au final, vous aurez une copie du fichier « torqueDemo_DEBUG.exe » dans le sous-répertoire « example » de votre répertoire Torque. Félicitation, vous avez créé avec succès la Torque Demo ! Si vous le souhaitez, vous pouvez exécuter la Torque Demo dans le débogueur du VC++ en allant dans le menu « Build », en sélectionnant « Start Debug » et en sélectionnant « Go ». Vous pouvez aussi utiliser le raccourci clavier F5. 154 / 223 Documentation de Torque V1.3.x Ça y est, votre système peut jouer joyeusement avec TGE et VC++ 6 ! A.2.5 En résumé Maintenant que vous avez créé la démonstration, lisez la section « Utilisation de l'application Torque Demo » pour apprendre comment l'utiliser. A.3 Création de Torque pour Mac OS X A.3.1 Préparation de votre système Vous n'avez pas grand-chose à faire que votre système fonctionne avec Torque. Sous OS X, assurez-vous simplement d'avoir le système requis indiqué ci-dessous : Matériels requis : • • • G3 ou + 64 Mo de RAM ou plus, très dépendant de votre application. Carte vidéo avec accélération 3D matérielle telle que les cartes du style AGP Radeon ou GeForce. Logiciels requis : • • • • Mac OS 10.2., ou 10.3.x (avec les dernières mises à jour) Les derniers pilotes pour votre carte vidéo. TCP/IP correctement configuré. Moteur OpenAL Outils de développement : • • Compilateur Xcode d'Apple, dernière version. Xcode existe depuis Mac OS X 10.x, et peut être mis à jour depuis le site des développeurs d'Apple. Il est également recommandé que vous téléchargiez quelques outils tels que JEdit (et le TorqueIDE pour Jedit) En résumé : Note : bien que le moteur ait des exigences assez minimales jusque dans le matériel, les performances de n'importe quel jeu créé en utilisant le TGE déprendront considérablement de la manière dont chaque jeu se sert des ressources disponibles. Les jeux TGE peuvent être de n'importe quel type, allant d'un petit jeu 2D très peu gourmand jusqu'au summum d'un jeu de rôle 3D, d'un FPS, d'une course, ou d'un simulateur de vol, et tout ce que vous pourrez rêver ! Torque est un moteur à hautes performances, il ne tient qu'à vous d'en tirer bénéfice. 155 / 223 Documentation de Torque V1.3.x Maintenant que vous avez téléchargé le code source du SDK, et que votre système est prêt, lisez la suite pour apprendre comment compiler le code en utilisant Xcode. A.3.2 Compilation du Torque Game Engine SDK avec Xcode Xcode un environnement de développement gratuit d'Apple fournit avec Mac OS X 10.3 et supérieur. Les révisions précédentes de l'environnement de développement d'Apple étaient appelées Project Builder. Torque peut fonctionner avec n'importe laquelle de ces versions, mais GarageGame ne supporte officiellement que les développements avec Xcode. Paramétrage de Xcode Soyez sûr que Xcode est installé et à jour. Il peut être installé à partir du CD-Rom Xcode Developer Tools fourni avec Mac OS X 10.3. Une fois installé, il peut être mis à jour à partir du site des développeurs d'Apple. Les instructions d'installation peuvent être trouvées dans le document About Xcode Tools.pdf sur le CD Xcode Developer Tools. Procédure 1 – Ouverture du fichier de projet Torque dans Xcode • • • Allez dans le répertoire où Torque a été téléchargé. Dans ce répertoire, vous verrez un autre répertoire appelé pb (abréviation de Project Builder, le prédécesseur de Xcode). Ouvrez le paquet appelé torque_pb_2_1.pbproj en double-cliquant dessus. La première fois que vous ouvrez torque_pb_2_1.pbproj, vous pouvez voir un avertissement indiquant qu'il a été créé pour une version plus ancienne de Xcode. Cliquez sur OK. Il est recommandé d'indiquer le répertoire example comme endroit de création. L'exécutable de Torque doit être dans le même répertoire que le fichier main.cs et autres éléments de script. Procédure 2 – Paramétrage du répertoire de création • • • • Ouvrir la fenêtre Xcode->Preferences. Sélectionnez l'icône Building dans la partie supérieure de la fenêtre. Sélectionnez le premier bouton radio Separate location for build products. Tapez dedans ../example. Ceci indiquera à Xcode de placer les éléments créés dans le répertoire example, relatif au répertoire de base dans lequel vous travaillez. C'est fini ! Félicitations ! Vous avez créé avec succès le Torque Game Engine SDK. Si vous désirez exécuter la démo, elle se trouvera dans ../example/Torque Demo OSX, ou ../example/Torque Demo Debug OSX, dépendant du projet ayant été sélectionné dans Xcode. Maintenant, lisez la section « Utilisation de l'application Torque Demo » pour apprendre comment l'utiliser. A.4 Création de Torque pour Linux A.4.1 Préparation de votre système Vous n'avez pas grand-chose à faire que votre système fonctionne avec Torque. Sous Linux, assurez-vous simplement d'avoir le système requis indiqué ci-dessous : Linux et OpenBSD Matériels requis : • • Pentium I, II, III, IV, AMD Athlon, 64, etc. 64 Mo de RAM ou plus, très dépendant de votre application. 156 / 223 Documentation de Torque V1.3.x • Carte vidéo avec accélération 3D matérielle telle que les cartes du style AGP Radeon ou GeForce. Logiciels requis : • • • • Xfree86 4.0 ou supérieure avec les pilotes 3D appropriés (GLX/DRI) pour votre carte vidéo. SDL SDK version 1.2 ou supérieure (1.2.3 ou supérieure recommandée). OpenAL runtime ou installation du SDK. Mesa3D version 3.4 ou supérieure (3.4.2 ou supérieure recommandée). Outils de développement : • • GNU make et g++ (version 2 ou 3). Assembleur Maintenant lorsque vous créez Torque, il sera placé immédiatement dans le bon répertoire. Ceci vous laissera exécuter le mode débogage dans Xcode, et vous évitera d'avoir à copier vos exécutables du répertoire de création par défaut. Compilation Xcode Maintenant que vous avez le fichier Project Torque ouvert, il suffit de cliquer sur le bouton Build Active Target pour lancer la compilation de Torque. • Vous pouvez rencontrer une erreur d'assemblage (linking) impliquant des fichiers OpenAL ou Ogg Vobis. Si ces erreurs surviennent, assurez-vous d'avoir les dernières versions des pilotes OpenAL pour Mac sur www.openal.org.NASM version 0.98 ou supérieure. En résumé : Note : bien que le moteur ait des exigences assez minimales jusque dans le matériel, les performances de n'importe quel jeu créé en utilisant le TGE déprendront considérablement de la manière dont chaque jeu se sert des ressources disponibles. Les jeux TGE peuvent être de n'importe quel type, allant d'un petit jeu 2D très peu gourmand jusqu'au summum d'un jeu de rôle 3D, d'un FPS, d'une course, ou d'un simulateur de vol, et tout ce que vous pourrez rêver ! Torque est un moteur à hautes performances, il ne tient qu'à vous d'en tirer bénéfice. Maintenant que vous avez téléchargé le code source, et que votre système est prêt, lisez la suite pour apprendre comment compiler le code pour Linux. A.4.2 Compilation du Torque Game Engine SDK sur Linux et OpenBSD Abstraction Ce guide décrit les étapes nécessaires afin de faire fonctionner le Torque SDK et la Torque Demo sur un système Unix. Si vous avez des problèmes, veuillez lire la section Problèmes connus, présentée plus loin, avant de vous aider des forums. Installation et création Étape 1 : Paramétrage du système Avant de commencer, vous devrez vous assurer que tous les prérequis matériels/logiciels décrits précédemment sont en place. Notez que la création du serveur dédié ne requiert que NASM et un compilateur fonctionnel. Beaucoup de distributions Unix installent les bibliothèques de tierce partie par défaut ou les incluent sur le CD d'installation. Si vous utilisez Mandrake, vous pouvez souhaiter utiliser le Software Manager pour installer les packages (MandrakeMenu->Configuration->Packaging->Software Manager). Vous aurez également besoin des fichiers de développement pour les packages, ils sont souvent dans un package appelé « devel », 157 / 223 Documentation de Torque V1.3.x par exemple Xfree86-devel. Une version statique de la bibliothèque GLU de Mesa est requise. Si votre système n'a pas un fichier libGLU.a, vous devrez installer Mesa à partir des sources pour l'avoir. OpenAL et SDL Pour SDL, il est recommandé que vous l'installiez à partir des sources si la version provenant de votre distribution est plus ancienne que la 1.2.4. Torque est sensible à la version d'OpenAL installée sur votre système. Une mauvaise version peut impliquer d'avoir aucun son ou causer le plantage de Torque. Vous pouvez tester le son en passant la souris au-dessus des boutons dans le shell. La procédure habituelle pour la compilation d'OpenAL et SDL est : cd repertoire_source ./configure (si vous obtenez une erreur « not found », faites d'abord « sh ./autogen.sh ») make su make installation ldconfig Si vous installez SDL ou OpenAL à partir des sources, notez que par défaut, ils s'installent eux-mêmes dans /usr/local/lib, un répertoire qui n'est pas recherché dans certaines distributions Unix (ex : RedHat). Si c'est le cas sur votre système, le chargement de la bibliothèque échouera lors du démarrage de Demo App. Vous devrez soit changer le préfixe d'installation (./configure -prefix=/usr), ou ajouter /usr/local/lib au fichier /etc/ld.so.conf (et lancer ldconfig en tant que root après avoir fait la modification). Étape 2 : Paramétrage du compilateur et création Il est recommandé d'utiliser GCC3 pour créer la source. Pour configurer la création, faites ceci : cd ~/projects/torque make -f mk/configure.mk OS=LINUX COMPILER=GCC3 BUILD=DEBUG Cette commande configure Torque pour une création de débogage GCC3 Linux. Pour voir une liste des autres configurations possibles, omettez les options OS, COMPILER et BUILD de la commande. Make vous dira si la configuration est valide après le lancement de la commande. Si c'est le cas, lancer la commande suivante pour créer la démo : cd ~/projects/torque make Si tout va bien, torqueDemo_DEBUG.exe sera créé et placé dans le répertoire « example ». Vous pouvez aussi créer le serveur dédié et les outils décrits ci-après, mais ils ne sont pas obligatoires. Si cela ne se passe pas bien, révisez votre configuration et consultez aussi la section Problèmes connus. Création du serveur dédié Vous pouvez vouloir seulement créer un serveur dédié. Ceci n'inclut pas le code client et n'a donc que peu de dépendances. Le serveur dédié n'est pas requis, cependant, puisque le client peut être exécuté avec le paramètre -dedicated. Pour créer le serveur dédié : make clean make dedicated L'étape « make clean » est très importante. Elle doit également être effectuée si vous désirez regénérer le client après la création du serveur dédié. 158 / 223 Documentation de Torque V1.3.x Le nom de l'exécutable du serveur dédié est torqueDemod. Outils Pour créer les outils, cd dans le répertoire « tools » et effectuez un « make ». buildWad, map2dif et texture2fm8 seront créés. Pour le moment, les outils n'ont pas été testés, donc rapportez les problèmes à mailto:[email protected] Étape 3 : Exécution de l'application de démonstration Pour lancer Demo Application, cd dans le répertoire « example » et utilisez les commandes suivantes : cd ~/projects/torque/example ./torqueDemo_DEBUG.exe L'application de démonstration devrait se lancer. Problèmes connus Généralités • • • • La compilation génère actuellement un nombre d'avertissements. La majorité de ceux-ci concerne des problèmes bénins de conversion float/int. Ces avertissements sont « normaux » et seront éventuellement supprimés. L'application de démonstration devra être lancée à partir du répertoire « example ». (Si pour quelque raison que ce soit vous devez la lancer d'ailleurs, utilisez le paramètre -chdir afin que l'application utilise le répertoire « example »). Torque a des problèmes de link avec GLU avec certaines distributions SUSE. La réinstallation de Mesa peut aider. Avec Unix, Torque stocke les fichiers créés (ex : .dso) dans « ~/garagegames/exename ». Ce répertoire est le premier recherché pour les fichiers devant être lus. Ce comportement peut être désactivé en supprimant le paramètre -DUSE_FILE_REDIRECT du fichier conf.UNIX.mk. Il peut également être désactivé à l'exécution avec le paramètre de ligne de commandes « -nohomedir ». Serveur dédié • • • • Le client peut être lancé comme serveur dédié, ou vous pouvez utiliser le serveur dédié seul créé (voir précédemment). Vous pouvez lancer le serveur dédié sans mission chargée avec cette commande : cd [example directory] ./torqueDemod_DEBUG.exe -dedicated Ou vous pouvez spécifier une mission sur la ligne de commandes avec le paramètre -mission, par exemple : cd [example directory] ./torqueDemod_DEBUG.exe -dedicated -mission fps/data/missions/waterWorld.mis Vous pouvez sortir du serveur dédié en tapant quit(); Client : • • • • • L'option -console peut être utile pour diagnostiquer les problèmes de démarrage. Il y a des distorsions avec certains effets sonores. Ceci est en cours d'investigation. Il y a des problèmes de performance lors de zoom. Ceci est en cours d'investigation. Certains systèmes ont des problèmes d'initialisation des CD audio (plantage ou blocage durant le démarrage). Si votre système est affecté, utilisez le paramètre de la ligne de commandes -nocdaudio . Notes sur le presse-papier (clipboard) : le client ne supporte pas le copier/coller avec le buffer primaire de sélection X (c'est-à-dire : sélection + bouton central de la souris). Vous devez utiliser explicitement les commandes couper/copier/coller dans chaque application. Pour Torque, ce sont 159 / 223 Documentation de Torque V1.3.x • CTRL-C (copier), CTRL-V (coller) et CTRL-X (couper). Notez aussi que suite à un bogue dans QT, le collage n'est pas supporté dans les applications KDE/QT (ceci est corrigé dans QT3). Si vous avez un système AMD avec une carte graphique AGP, vous pouvez faire l'expérience de blocages dans les applications 3D. Le correctif suivant provient du site Gentoo linux : Si vous avez des blocages sur votre système Athlon, Duron ou Athlon MP lorsque vous utilisez une carte vidéo AGP, essayez de passer l'option mem=nopentium à votre noyau (utilisant GRUB ou LILO) au démarrage (boot). Ceci indique à Linux d'employer à nouveau les pages évitant ce bogue CPU). BSD Le support de BSD n'est pas actuellement maintenu. Il le pourra peut-être dans le futur. Si vous êtes intéressé par le support de BSD, envoyez un email à [email protected] . Obtenir de l'aide Si vous avez des problèmes de création ou d'utilisation de Torque, la première chose que vous devrez faire est de revoir votre configuration et de parcourir à nouveau la documentation. Si vous ne pouvez pas régler le problème, vous pouvez demander de l'aide à la communauté Torque, via les forums. Veuillez poster votre message dans le forum « Getting Started » de la zone privée des forums. Inclure le mot « Linux » quelque part dans le sujet pour rendre aisément accessible votre message via une recherche. Environnements de développement pour Torque Cette section couvre certains environnements de développement pouvant être utilisés pour travailler avec Torque. Cependant, un tutoriel complet sur ces outils est en dehors du cadre de ce document, cette section offre certains trucs pour le paramétrage et l'utilisation de ces outils. KDevelop KDevelop 3 fonctionne bien mieux avec Torque. • • • • • Installez Kdevelopp si vous ne l'avez pas déjà fait. Sur les systèmes Mandrake, ceci peut être réalisé via le Software Manager. Note : si vous utilisez Gnome et n'avez pas KDE installé du tout, vous ne serez pas capable d'utiliser la console intégrée dans KDevelop. Bien que non obligatoire, cette console est utile. Ensuite, lancez le setup de Kdevelop si vous ne l'avez pas déjà fait, et effectuez les choix judicieux... la plupart des options peuvent être acceptées avec les valeurs par défaut. Après le démarrage de Kdevelop, allez dans Options->KDevelop Setup. Vous pouvez vouloir changer le répertoire vers le répertoire du projet par défaut. Maintenant, allez dans Project->Generate Project File. Choisissez le répertoire de Torque et cliquez sur OK. Vous pouvez voir un message disant « No Makefile.am found, are you sure you want to do this? ». Si cela est le cas, sélectionnez « yes ». Ensuite, vous verrez une certaine activité dans la fenêtre des messages. Lorsque cela est fini, votre projet peut ne pas être ouvert ; dans ce cas, allez dans Project->Open et naviguez jusqu'au répertoire dans lequel vous avez généré le fichier du projet. Sélectionnez le fichier nouvellement généré – *.kdevprj ; il prendra probablement quelques minutes à charger dues au nombre de fichiers dans le projet. Allez dans Project->Options. Dans l'onglet General, décoché Modify Makefiles. Ensuite, allez dans l'onglet Make options et cochez Run make in et assurez-vous qu'il est paramétré sur ./ . Puis allez dans l'ongle Binary et indiquez le chemin et le fichier example/torqueDemo_DEBUG.exe. Cliquez OK. Vous pouvez avoir un message indiquant que les nouveaux fichiers makefiles seront générés. Ceux-ci peuvent encombrer votre répertoire Torque, mais ne vous inquiétez pas, car le make échouera. Ensuite, le répertoire sera rafraîchi. Ceci peut prendre quelques minutes. Vous pourriez vouloir effectuer une sauvegarde totale (Save-all) juste au cas où quelque chose se passerait mal pour une quelconque raison. Maintenant, il est temps de compiler votre projet. Allez simplement dans Build->Make. Prêtez attention à la 160 / 223 Documentation de Torque V1.3.x fenêtre des messages pour voir si des erreurs surviennent. Pour exécuter la démonstration après sa compilation réussie, vous devrez faire Build->Execute with Arguments et mettez -chdir dans la fenêtre.Pour déboguer la démonstration, vous devrez faire Debug->Start (other)...->Debug with Arguments et entrez -chdir example dans la fenêtre. Note : Avant le débogage, vous devez placer des points d'arrêt et vous ne pouvez pas les placer durant le débogage comme en Visual C++. Si le projet compile, mais bloque sans aucune notification, regardez la section Problèmes connus plus avant pour avoir des informations sur l'option -console. XEmacs Tandis que la plupart des environnements « visuels » ne le sont pas, XEmacs est un environnement d'édition assez bon avec Torque. Voici quelques trucs pour l'utilisation de XEmacs avec Torque. • • • • La commande grep-find (M-x grep-find) est utile pour la recherche d'une expression régulière au travers des fichiers. Par défaut, il cherchera dans les répertoires dans le répertoire du buffer courant. Faites M-x pwd pour afficher le répertoire où vous êtes. Faites M-x man grep, pour afficher plus d'information sur grep. Les commandes compile et recompile peuvent être utilisées pour créer Torque à partir de IDE. La différence entre les deux est que compile vous demandera une ligne de commandes et recompile utilisera juste la dernière commande compile. Vous pouvez effectuer un différentiel visuel entre deux fichiers avec la commande M-x ediff-files. La commande M-x ediff-directories est similaire, sauf que vous pouvez effectuer un différentiel d'un jeu de fichiers dans un répertoire. Vous pouvez déboguer à partir XEmacs, ou vous pouvez déboguer en utilisant un des outils décrits ci-dessous. Outils de débogage • • • La commande gdb peut être utilisée pour analyser les vidages-mémoires (core dumps) pour effectuer un rapport de contexte (backtrace). Lancez gdb -c core torqueDemo_DEBUG.exe, ensuite tapez where. Tous les systèmes n'effectuent pas par défaut un vidage-mémoire ; vous pouvez l'activer avec la commande ulimit -c 500000000. Vous pouvez utiliser gdb pour le débogage interactif au travers de son interface ne soit pas aisée pour les débutants. Certains débogueurs visuels incluent ddd et gvd, fonctionnant tous les deux avec Torque. Si Torque bloque, vous pouvez lui envoyer un SIGSEGV. Ceci l'obligera à planter, et à partir de là, vous pourrez utiliser la commande gdb précédente pour analyser le vidage-mémoire. Pour effectuer ceci, utilisez la commande ps pour récupérer le pid (process id) de Torque (ps -aux | grep torque), puis tuez Torque en envoyant SIGSEGV au plus bas pid rapporté par ps (ex: kill -11 8686). Installation avec le Windows SDK Note : le problème numéro un que les gens rencontrent lors de l'installation à partir d'un répertoire Windows est dans ce cas lib/openal/LINUX obtenu en minuscules. Si vous avez des erreurs de compilation openal, assurez-vous que ce répertoire est « LINUX » et non « linux ». Vous pouvez installer le code du Windows SDK. Cependant, cette méthode d'installation nécessite que vous ayez une installation de Windows disponible, avec les fichiers accessibles à votre partition Unix. Bootez sous Windows et installez le SDK à un endroit accessible à votre installation Unix. Rebootez sous Unix et copiez les fichiers de la partition Windows dans votre système Unix. Les fichiers header et source C++ distribués avec le Windows SDK nécessite d'être convertis du système Windows/DOS de fin de lignes CR/LF en utilisant seulement LF. Le script de shell unixchange.sh situé dans le répertoire torque/tools/unix est fourni pour cela. Le script devra être exécuté une seule fois à partir du répertoire torque/tools/unix avant de lancer makefile. Le script unixchange.sh peut aussi être converti avant de le lancer. Vous pouvez utiliser l'utilitaire « dos2unix » pour convertir le fichier avant de le lancer. Cet utilitaire est un élément du package unix2dos et 161 / 223 Documentation de Torque V1.3.x vient avec RedHat Linux et probablement beaucoup d'autres distributions, cependant il peut ne pas être installé par défaut. 162 / 223 Documentation de Torque V1.3.x Annexe B : Utilisation de l'application Torque Demo B.1 Aperçu L'application de test de Torque, torqueDemo, fournit une base simple pour la création de jeux et mods multijoueurs aussi bien que le support pour des outils intégrés. L'exemple actuel est un FPS (first person shooter) chargé par défaut. L'exemple de jeu FPS est supposé vous exercer sur une partie des fonctionnalités de base du Torque Engine. Ce n'est pas une démonstration complète des capacités du Torque Engine, ni un exemple complet de ses nombreux dispositifs. B.2 Lancement de l'application Avant de lancer l'application de démonstration, assurez-vous que votre système répond aux prérequis pour votre plate-forme : Windows, Mac OS X ou Linux. L'application de test torqueDemo doit être exécutée à partir du répertoire /torque/example qui est la racine de l'arborescence des ressources de l'exemple. Le répertoire /torque/example est complet : il contient tous les scripts, fichiers graphiques ou sonores, et toutes les autres données nécessaires pour faire fonctionner l'application de test. Lancement de l'application à partir de la ligne de commandes (sous Windows) : cd c:\torque\example torqueDemo L'application de démonstration peut être lancée sous deux modes : avec ou sans interface cliente. Le lancement de l'interface graphique est le comportement par défaut. Le lancement de l'application en mode « dédié » saute l'initialisation de l'interface graphique et cliente. Ce mode est utilisé pour fonctionner en serveur de jeu dédié et consommer moins de ressource, mais il n'est pas directement jouable. Vous devez vous connecter à un serveur dédié en utilisant une autre instance de l'application de test fonctionnant en mode client. Pour entrer en mode dédié, en utilisant des arguments de commande, tapez les lignes de commandes suivantes : cd c:\torque\example torqueDemo -dedicated -mission fps\data\missions\test1.mis Les jeux (serveurs) peuvent aussi être hébergés via l'interface client, et un client peut jouer au jeu hébergé. B.3 Arguments de la ligne de commandes de Torque Demo torqueDemo [-fullscreen] [-windowed] [-noSound] [-openGL] [-directX] [-voodoo2] [-autoVideo] [-prefs file] [-dedicated] [-mission mission] [-connect address] [-log level] [-mod modName] [-game gameName] [-show shapeFile] [-console] [-jSave file] [-jPlay file] [-jDebug file] [-help] Paramètre Fonction -fullscreen Fonctionne en mode plein écran -windowed Fonctionne en mode fenêtré -noSound Désactivation du son -openGL Utilisation du pilote OpenGL -autoVideo Détection automatique du pilote vidéo -prefs fichier Chargement du fichier de préférences indiqué -dedicated Fonctionne en mode serveur dédié 163 / 223 Documentation de Torque V1.3.x Paramètre Fonction -mission mission Chargement du fichier de mission indiqué -connect adresse Connexion à un serveur -log niveau Niveau de journalisation = (0, 1, 2) -mod nom_mod Chargement du fichier mod indiqué -game nom_jeu Chargement du jeu indiqué, effacement de tous les mods préalablement chargés -show [fichier.dts] Lance le mod show et optionnellement charge le fichier spécifié -console Lance une fenêtre console séparée -jSave fichier Enregistre un journal -jPlay fichier Rejoue un journal -jDebug fichier Identique à jPlay, excepté qu'un break de débogage (int3) est généré lors de la fin du journal -help Affiche l'aide dans la console B.4 Raccourcis clavier Fonctions diverse Messagerie instantanée Contrôle de vue Mouvement La liste suivante détaille certains raccourcis clavier par défaut utilisés dans le jeu FPS de démonstration. Le fichier de script qui gère ces touches peut être trouvé dans le fichier torque/fps/client/scripts/default.bind.cs. Touche Fonction w Avant s Arrière a Gauche d Droite e Zoom r Règle le zoom FOV TAB Vue première/troisième personne Alt + c Bascule entre caméra et joueur u Envoi d'un message de chat public y Envoi d'un message de chat d'équipe F1 Aide en ligne F7 Donne le contrôle au joueur et le positionne à l'endroit de la caméra F8 Donne le contrôle à la caméra et la positionne à l'endroit du joueur F9 Bascule entre mode fil de fer, débogage d'interior, et rendu normal F10 Passe en éditeur GUI F11 Passe en éditeur de mission B.5 Jeux et mods L'application de test est conçue pour supporter de multiples jeux, chaque possibilité fonctionnant en multiples mods (les mods dont des modifications de tierce partie). Ceci est possible, car le code C++ du jeu contient un 164 / 223 Documentation de Torque V1.3.x jeu flexible de fonctionnalités du noyau (comme les contrôles GUI, mouvement et animation des joueurs, etc.) qui est contrôlé à partir du langage de script. Ainsi, les nouveaux jeux peuvent être implantés avec Torque en fournissant simplement de nouveaux scripts et fichiers graphiques et sonores. Les jeux et mods sont organisés en répertoires racines de niveau d'application et peuvent être explicitement chargés à partir de la ligne de commandes en utilisant les arguments -game nom et -mod nom. Un seul jeu peut être chargé à la fois, mais de multiples mods peuvent être chargés sur un jeu. Lorsqu'un jeu est chargé, il accède uniquement au répertoire common, qui contient les scripts noyau et les données partagées par les jeux, ainsi que son propre répertoire. Exemples chargement de jeux et de mods : cd c:\torque\example torqueDemo -game fps torqueDemo -game fps -mod show B.6 Outils intégrés Un jeu d'outils du Torque Until est intégré dans l'application de test, et par conséquent, dans n'importe quel jeu utilisant l'infrastructure de base de l'application d'exemple. B.6.1 L'éditeur de mission (Mission Editor) L'éditeur de mission est l'outil primaire pour la création et l'édition des fichiers de mission. L'éditeur est constitué de plusieurs sous-composants incluant l'éditeur de monde (World Editor) qui inclut un créateur d'objet, un inspecteur d'objet et un éditeur de zone de mission, aussi bien qu'un éditeur de terrain (Terrain Editor) qui inclut un éditeur de niveau, un générateur de terrain et d'un outil d'application de textures basé sur des règles. Une mission peut être éditée à la volée : dans une mission, l'éditeur peut être activé en utilisant la touche F11. B.6.2 L'éditeur de GUI (GUI Editor) L'éditeur d'interface graphique est utilisé pour créer et éditer les écrans d'interface intégrés au jeu. Ceci inclut les écrans de démarrage, les boîtes de dialogue, etc. Les écrans GUI peuvent être édités à la volée. L'éditeur est activé en utilisant la touche F10. B.6.3 L'outil de visualisation (Show Tool) Cet outil n'est pas strictement un outil intégré (il n'est pas activable durant le jeu), il est indiqué ici, car il est implémenté comme un mod. L'outil de visualisation est utilisé pour charger et tester les fichiers DTS. L'outil fournit un nombre de boîtes de dialogue pour le test des formes incluant l'animation, le test des niveaux de détail, etc. B.7 Arborescence des répertoires de l'application Le répertoire c:\torque\example est la racine de l'application de test et contient tous les scripts, fichiers graphiques et sonores, et toutes les données nécessaires pour faire fonctionner l'application de test. Excepté pour common, les répertoires dans la racine de l'application représentent les jeux et mods chargeables. Repérez dans le répertoire c:\torque\example : \common Ce n'est pas vraiment un jeu ou un mod, mais il contient actuellement l'infrastructure de scripts utilisée par les jeux, aussi bien que les scripts et données nécessaires pour lancer les outils intégrés. \client Scripts de base de support client incluant la communication client->serveur \debugger Scripts de support pour le débogueur de script intégré \editor Support pour les outils intégrés \help Aide client 165 / 223 Documentation de Torque V1.3.x \lighting Textures, éclairages dynamiques multipasses \fps \show \server Scripts de base du support serveur \ui Divers. Contrôles GUI et textures utilisées par les outils intégrés Contient les scripts, les fichiers graphiques et sonores, et les missions implémentant l'exemple de jeu FPS \client Scripts de jeu et interface utilisateur client \data La racine de l'arborescence des données qui est partagée par le serveur et le client. Ceci inclut les bâtiments, les fichiers de mission, les formes, les textures, les ciels, les sons, les terrains et l'eau. \server Scripts qui implémentent le jeu FPS actuel géré par le serveur. Ce répertoire est accédé uniquement par les serveurs dédiés et les clients qui hébergent les jeux. Un mod qui contient l'interface utilisateur et tous les scripts implémentant l'outil de visualisation. 166 / 223 Documentation de Torque V1.3.x Annexe C Fonctions et commandes de la console Torque Voici la liste de chaque fonction et commande de la console dans le TGE. Des exemples pour chaque commande et fonction seront donnés avec son prototype et sa valeur de retour. C.1 Terminologie Terme Signification Chaîne (string) Fait référence à n'importe quelle collection de caractères entre apostrophes (') ou guillemets (") Booléen (boolean) Fait référence à une valeur numérique ayant pour valeur 1 ou 0 (1 étant true et 0 étant false) Numérique (numeric) Fait référence à un type de données numériques intrinsèque (nombre entier, booléen, nombre décimal, et/ou valeur hexadécimale). Variable globale (global variable) Fait référence à une variable qui est accessible de n'importe quelles fonctions ou n'importe quel script Variable locale (local variable) Fait référence à une variable qui n'est accessible que de la fonction ou du script où elle a été créée. Variable Fait référence à une chaîne commençant par un signe de pourcentage (%) indiquant une variable locale ou par un signe dollar ($) indiquant une variable globale. Chaîne marquée (tagged string) Une chaîne marquée est utilisée pour n'importe quelle constante de chaîne qui est transmise via une connexion. La chaîne marquée entière n'est envoyée qu'une seule fois. Lorsqu'on y fait référence, un marqueur court (une valeur numérique) identifiant cette chaîne est envoyé au lieu de la chaîne entière. C.2 Mots clefs réservés break case continue datablock default else false function if for new or package return switch switch$ true while C.3 Opérateurs de script Opérateurs = Signification Assigne la valeur du second opérande au premier opérande. 167 / 223 Documentation de Torque V1.3.x Opérateurs Signification + Addition. Ajoute deux nombres ensemble. - Soustraction. Soustrait deux nombres. * Multiplication. Multiplie deux nombres. / Division. Divise deux nombres. % Modulo. Calcule le reste de la division de deux nombres. += Ajoute deux nombres et assigne le résultat au premier. -= Soustrait deux nombres et assigne le résultat au premier. *= Multiplie deux nombres et assigne le résultat au premier. /= Divise deux nombres et assigne le résultat au premier. %= Calcule le modulo de deux nombres et assigne le résultat au premier. ++ Incrémentation. Ajoute la valeur 1 à une variable représentant un nombre. -- Décrémentation. Soustrait la valeur 1 à une variable représentant un nombre. ~ NON logique (NOT). Inverse les bits de l'opérande. | OU logique (OR). Renvoie un bit à 1 s'il l'est dans un des opérandes. & ET Logique (AND). Renvoie un bit à 1 s'il l'est dans les deux opérandes. ^ OU EXCLUSIF logique (XOR). Renvoie un bit à 1 s'il l'est que dans un des opérandes. << Décalage gauche de bits. Décale la représentation binaire du premier opérande vers la gauche d'un nombre de bits indiqué dans le second opérande, mettant des 0 à droite. >> Décalage droit de bits. Décale la représentation binaire du premier opérande vers la droite d'un nombre de bits indiqué dans le second opérande, mettant des 0 à gauche. |= Effectue un OU logique et assigne le résultat au premier opérande. &= Effectue un ET logique et assigne le résultat au premier opérande. ^= Effectue un OU EXCLUSIF logique et assigne le résultat au premier opérande. <<= Effectue un décalage gauche et assigne le résultat au premier opérande. >>= Effectue un décalage droit et assigne le résultat au premier opérande. @ Concatène une ou plusieurs valeurs ensemble pour former une nouvelle valeur. NL Concatène une valeur avec une nouvelle ligne pour former une nouvelle valeur. TAB Concatène une valeur avec une tabulation pour former une nouvelle valeur. SPC Concatène une valeur avec un espace pour former une nouvelle valeur. ! Évalue l'inverse de la valeur spécifiée. && Requiert deux valeurs true pour que le résultat soit true. || Requiert uniquement une valeur true pour que le résultat soit true. == Évalue l'égalité des deux valeurs. != Évalue l'inégalité des deux valeurs. < Évalue si la première valeur est inférieure à la seconde valeur. > Évalue si la première valeur est supérieure à la seconde valeur. <= Évalue si la première valeur est inférieure ou égale à la seconde valeur. >= Évalue si la première valeur est supérieure ou égale à la seconde valeur. $= Évalue l'égalité des deux chaînes. 168 / 223 Documentation de Torque V1.3.x Opérateurs !$= Signification Évalue l'inégalité des deux chaînes. C.4 Commandes et fonctions Les commandes et fonctions de console suivantes sont énumérées dans l'ordre comme indiqué dans ConsoleDoc. OpenAlInitDiver (void); utilisé pour initialiser le pilote sonore. Retourne une valeur numérique. OpenAlShutdownDriver (void); utilisé pour désactiver le pilote sonore. Retourne une valeur numérique. OpenAlRegisterExtensions (void); cette fonction n'a aucun corps et n'a aucun code de script ou moteur associé. Ne retourne pas de valeur alGetString (Alenum enum); utilisé pour retourner la chaîne représentant l'ALenum spécifié. Retourne une chaîne. alxCreateSource alxCreateSource (AudioProfile profil [, int x, int y, int z] ); (AudioDescription description, string nomfichier, int x, int y, int z] ); crée et valide la source audio (fichier sonore), et le lit pour être joué. Retourne une valeur numérique. alxSourcef (AudioHandle handle, Alenum enum, float Valeur ); utilisé pour affecter la valeur de Alenum pour le handle spécifié. Pas de valeur retournée. 169 / 223 Documentation de Torque V1.3.x alxSource3f (AudioHandle handle, Alenum enum, {string Xyz, int x, int y, int z} ); utilisé pour affecter la valeur de Alenum pour le handle spécifié. Pas de valeur retournée. 170 / 223 Documentation de Torque V1.3.x Annexe D Les Datablocks de Torque Les datablocks sont une caractéristique très importante du TGE. Ils peuvent aider pour définir rapidement des données communes pour divers objets de jeu, et peuvent être utilisés en conjonction avec les capacités réseau de Torque pour étendre et accélérer le jeu réseau. Le TGE propose plusieurs datablocks prédéfinis que les concepteurs de jeux peuvent utiliser pour implémenter rapidement plusieurs sortes communes d'objets de jeu. Les concepteurs peuvent créer également leurs propres nouveaux types de datablocks. Cette annexe offre une liste de référence de tous les datablocks qui sont prédéfinis dans Torque, et fournit une description détaillée de chaque champ membre exposé pour TorqueScript. Cette référence approche les datablocks comme ils sont utilisés dans TorqueScript. Un mot sur le style : cette référence est écrite d'un point de vue technique, et dans l'intérêt d'offrir des descriptions les plus précises possible, et utilise un langage technique. Le but est de fournir des descriptions des champs des datablocks qui sont les plus proches du code source, sans faire une copie de celui-ci. Pour cela, cette référence ne doit pas être abordée comme un tutoriel sur les datablocks. Bien sûr, elle tâche d'être aussi claire que possible sans compromettre l'exactitude technique des descriptions offertes. D.1 SimDataBlock Le datablock le plus basique disponible à utiliser dans TorqueScript dans le SimDataBlock. Ce datablock est extrêmement simple ; en fait, par défaut, il ne définit aucune donnée pouvant être visible dans TorqueScript. Cependant, le SimDataBlock peut être utile dans un script comme base à partir de laquelle on peut construire des datablocks plus détaillés. Dans le moteur lui-même, tous les datablocks sont dérivés de SimDataBlock. Exemple : création d'un datablock SimDataBlock dans TorqueScript. Dans cet exemple, nous introduirons la syntaxe utilisée pour travailler avec les datablocks dans TorsqueScript en créant un nouveau SimDataBlock. Le nouveau SimDataBlock sera nommé « myDataBlock », et nous lui donnerons un nouveau champ membre, appelé « newMemberItem ». Les noms « myDataBlock » et « newMemberItem » sont arbitraires, nous pouvons donner n'importe quel nom. datablock SimDataBlock(myDataBlock) { newMemberItem = "Hello"; }; echo(myDataBlock.newMemberItem); De l'exécution de ce code résultera l'affichage du texte « Hello » dans la console. Des datablocks complexes sont définis d'une manière similaire. Notez que les datablocks de n'importe quel type doivent avoir au moins un champ membre défini et avec une donnée afin d'être valides. L'élément peut être soit prédéfini dans le moteur ou ajouté dans le script. Le code précédent ne fonctionnera pas si nous n'avons pas défini newMemberItem (ou d'autres champs membres). D.2 GameBaseData GameBaseData est un autre datablock très simple qui fournit une bonne base à partir de laquelle on peut construire des datablocks plus avancées. GameBaseData est légèrement plus complexe que SimDataBlock. En particulier, GameBaseData peut être utilisé pour créer des datablocks pouvant être vus dans l'éditeur de mission (Mission Editor). De même, GameBaseData ajoute le support pour l'enregistrement de démonstration (l'enregistrement de démonstration est la possibilité d'enregistrer les jeux dans le TGE comme ils sont joués). La table ci-dessous décrit les deux champs membres prédéfinis de GameBaseData. 171 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description category string className string GameBaseData Identifie quelle catégorie dans les objets de l'éditeur de mission basés sur ce datablock sera montrée. Utilisé pour identifier cette classe de datablock. La valeur peut être surchargée dans un script. Exemple : création d'un datablock GameBaseData dans TorqueScript Dans cet exemple, nous créons un nouveau datablock GameBaseData. Ce processus est similaire à celui utilisé pour créer un SimDataBlock. datablock GameBaseData(myGBD) { category = "Brand New Category"; newItem = "Brand new field"; }; echo(myGBD.category); echo(myGBD.newItem); echo(myGBD.className); Le lancement de ce code affichera les lignes suivantes dans la console. Brand New Category Brand new field GameBaseData Notez que nous n'avons pas initialisé nous-mêmes le champ className. La valeur est initialisée par le moteur. Cependant, nous pouvons surcharger la className, si nous le souhaitons. Comme mentionné ci-dessus, spécifier une catégorie pour un datablock GameBase définit une nouvelle catégorie de formes dans l'éditeur de mission. Pour tester ceci, ouvrez l'éditeur de mission en appuyant sur F11, ensuite allez dans le menu Window, et cliquez sur World Editor Creator. Dans l'interface GUI qui apparaît, cliquez le nœud Shapes, et vous verrez une nouvelle catégorie appelée Brand New Category. Cliquez sur cette catégorie pour déployer, et vous verrez myGBD. Note : si vous tapez simplement le code précédent dans la console, vous devrez lancer une nouvelle mission avant que les modifications prennent effet. D.3 ShapeBaseData Avec ShapeBaseData, les datablocks commencent à devenir plus complexes et utiles. ShapeBaseData est dérivé de GameBaseData et offre toutes les mêmes fonctionnalités de base, avec beaucoup de nouvelles caractéristiques. ShapeBaseData définit les données de rendu : les champs peuvent être initialisés pour spécifier une forme pouvant être rendue, certains effets de texture, et un comportement de destruction. Les données relatives à la caméra sont également définies. Les comportements d'endommagement peuvent aussi être spécifiés. ShapeBaseData définit aussi un champ relatif au contrôle CRC27 qui est une fonction de sécurité. Les informations physiques sont définies, bien que par défaut, les objets contenant un datablock ShapeBaseData n'utilisent pas des informations physiques – le plus souvent, les données physiques sont utilisées dans des datablocks qui sont eux-mêmes dérivés de ShapeBaseData. De plus, les données d'énergie sont définies, mais elles pourront être supprimées dans le futur. Un champ relatif au comportement IA 28 est aussi défini, 27 Un contrôle de redondance cyclique ou CRC (Cyclic Redundancy Check) est un outil permettant de détecter les erreurs de transmission par ajout de redondance. La redondance ajoutée communément appelée (à tort) somme de contrôle (checksum) est obtenue par un type de hachage sur l'ensemble des données. Les CRCs sont calculés avant et après la transmission ou duplication, puis comparés pour s'assurer que ce sont les mêmes. Les calculs de CRC les plus utilisés sont construits de manière à ce que les erreurs de certains types, comme celles dues aux interférences dans les transmissions, soient toujours détectées. Wikipédia 28 L'intelligence artificielle, souvent abrégée avec le sigle IA, est définie par l’un de ses créateurs, Marvin Lee Minsky, comme « la construction de programmes informatiques qui s’adonnent à des tâches qui sont, pour l’instant, accomplies de façon plus 172 / 223 Documentation de Torque V1.3.x mais peut aussi être supprimé. Des champs relatifs HUD29 sont aussi spécifiés, mais ces champs ne sont pas entièrement supportés et seront certainement supprimés. Le TGE définit plusieurs datablocks qui sont dérivés de ShapeBaseData, comme nous le verrons bientôt. Pour cela, c'est une bonne idée de vous familiariser par vous-même avec les champs de ShapeBaseData. Ci-dessous, la table des champs de données fournis dans ShapeBaseData, accompagnés d'une brève description. Nom Type category String className String Valeur par défaut Description Identifie quelle catégorie dans les objets de l'éditeur de mission basés sur ce datablock sera montrée. GameBaseData Utilisé pour identifier cette classe de datablock. La valeur peut être surchargée dans un script. Données de rendu shapeFile Filename cloakTexture Filename emap Boolean NULL Nom du fichier de forme. Spécifié comme une chaîne (string). Le nom d'un fichier de texture, qui peut être utilisé pour rendre un effet de dissimulation. Note : ce champ peut être supprimé de la description de ShapeBaseData. False Indique si le placage d'environnement doit être activé pour cet objet. Données d'effet de destruction Explosion ExplosionData Ptr NULL Si indiqué, ce champ doit pointer sur un autre datablock de type ExplosionData. underwaterExplosion ExplosionData Ptr NULL Voir le champ Explosion. underWaterExplosion doit suivre la même spécification, mais est prévu pour activer un effet d'explosion indépendante à utiliser sous l'eau. Debris DebrisDataPtr NULL Si indiqué, ce champ doit pointer sur une autre datablock de type DebrisData, comme défini dans le moteur. debrisShapeName Filename renderWhenDestroyed Boolean Le nom du fichier de la forme associée avec le champ Debris True Indique si 'objet doit être rendu après sa destruction. Données de caméra cameraMaxDist Float 0.0 Distance maximale permise entre la caméra et les yeux. cameraMinDist Float 0.2 Distance minimale permise entre la caméra et les yeux. cameraDefaultFOV Float 90.0 L'angle de champ de vision (field of vision) par défaut, mesuré en degrés. satisfaisante par des êtres humains, car elles demandent des processus mentaux de haut niveau tels que : l’apprentissage perceptuel, l’organisation de la mémoire et le raisonnement critique ». Wikipédia. 29 HUD est l'abréviation de Head Up Display soit affichage tête haute consistant à superposer des informations nécessaires au pilotage, à la navigation ou à la réalisation de la mission sur l’environnement extérieur. Il permet au pilote de surveiller son environnement en même temps que des informations fournies par ses instruments de bord. Wikipédia. 173 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description cameraMinFOV Float 5.0 L'angle minimal autorisé pour l'angle de vision (en degrés). cameraMaxFOV Float 120.0 L'angle maximal autorisé pour l'angle de vision (en degrés). useEyePoint Boolean False Indique si nous devrons utiliser le point de vue de la forme comme point de vue de la caméra. observeThroughObject Boolean False Indique si nous observons l'objet via sa caméra et FOV. cameraDefaultFOV Float 90.0 L'angle de champ de vision par défaut, mesuré en degrés. firstPersonOnly Boolean False Indique si seule la vue first-person peut être utilisée. Données de sécurité computeCRC Boolean False Indique si le CRC de shapeFile doit correspondre à celui envoyé par le serveur. Données physiques mass Float 1.0 Propriété de masse utilisée dans les simulations physiques. density Float 1.0 Propriété de densité utilisée dans les simulations physiques. drag Float 0.0 Propriété de résistance utilisée dans les simulations physiques. Champs spécifiques aux dommages isInvincible Boolean False Indique si l'entité doit être traitée comme insensible aux dommages. maxDamage Float 1.0 Le dommage maximal que l'entité peut subir. destroyedLevel Float 1.0 Le point auquel l'entité est considérée détruite, en relation avec le dommage subit par rapport au dommage maximal. Les valeurs valides vont de 0.0 à 1.0. Note : ce champ peut être supprimé dans le futur. disabledLevel Float 1.0 Le point auquel l'entité est considérée désactivée, en relation avec le dommage subit par rapport au dommage maximal. Les valeurs valides vont de 0.0 à 1.0. repairRate Float 0.0033 Taux de réparation par unité de temps (tick) Données d'énergie MaxEnergy Float inheritEnergyFromMou Boolean nt 0.0 Valeur d'énergie maximale. Note : ce champ peut être supprimé dans le futur. False Indique si le moteur doit transférer l'énergie d'une source vers l'objet. Note : ce champ peut être supprimé dans le futur. Données IA aiAvoidThis Boolean False Indique si l'IA doit éviter cet objet. Note : ce champ peut être supprimé dans le futur. 174 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description Données HUD hudImageName String Note: ce champ n'est pas pleinement supporté et peut être supprimé dans le futur. hudImageNameFriendl String (array) y Note: ce champ n'est pas pleinement supporté et peut être supprimé dans le futur. hudImageNameEnemy String (array) Note: ce champ n'est pas pleinement supporté et peut être supprimé dans le futur. hudRenderCenter Boolean (array) False Note: ce champ n'est pas pleinement supporté et peut être supprimé dans le futur. hudRenderModulated Boolean (array) False Note: ce champ n'est pas pleinement supporté et peut être supprimé dans le futur. hudRenderAlways Boolean (array) False Note: ce champ n'est pas pleinement supporté et peut être supprimé dans le futur. hudRenderDistance Boolean (array) False Note: ce champ n'est pas pleinement supporté et peut être supprimé dans le futur. hudRenderName Boolean (array) False Note: ce champ n'est pas pleinement supporté et peut être supprimé dans le futur. La création d'un bloc de données ShapeBaseData fonctionne de la même manière que la création d'un datablock GameBaseData ; entrez simplement des valeurs pour les champs que vous souhaitez modifier à partir des données par défaut, et ajoutez toutes les entrées que vous désirez. Comme vous pouvez le voir, ShapeBaseData commence par définir quelques champs utiles qui peuvent être utilisés pour spécifier rapidement le comportement du gameplay. Ensuite, nous jetterons un coup d'œil aux datablocks dérivés de ShapeBaseData. D.4 PlayerData La classe de datablock PlayerData nous permet de spécifier facilement plusieurs aspects des comportements des personnages des joueurs. PlayerData inclut tous les champs de ShapeBaseData, et en ajoute plusieurs autres qui sont spécialement dédiés aux joueurs et personnages dans le jeu. Nous allons jeter un coup d'œil sur chaque champ de PlayData. Dans un souci de clarté, les champs définis dans ShapeBaseData sont omis dans la table suivante. Nom Type Valeur par défaut Description Données de rendu renderFirstPerson Boolean True Identifie si la forme du joueur doit être rendue en mode FOV. Donneés d'effets spéciaux decalData DecalDataPtr NULL Si indiqué, ce champ doit pointer sur un autre datablock de type DecalData. decalOffset Float 0.0 Offset à partir du centre du joueur à partir duquel l'étiquette devra être affichée ; devra être corrélé avec la distance du centre du joueur au centre du pied droit du joueur. 175 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut footPuffEmitter FootPuffEmitterDataPtr NULL Si indiqué, ce champ doit pointer sur un autre datablock de type FootPuffEmitterData. footPuffNumParts Integer 15 Nombre de particules de poussière à générer lors de la marche d'un personnage. footPuffRadius Float 0.25 Rayon de l'émission de particules autour des pieds. dustEmitter ParticleEmitterDataPtr NULL Le datablock ParticleEmitterData sera utilisé pour émettre des particules suivant les traces de pas. FootSoftSound AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons pour les pas doux. FoorHardSound AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons pour les pas durs. FoorMetalSound AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons pour les pas sur du métal. FootSnowSound AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons pour les pas sur de la neige. FootShallowSound AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons pour les pas dans de l'eau peu profonde. FootWadingSound AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons de pataugement dans de l'eau. FootUnderwaterSound AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons pour les pas sous l'eau. FootBubblesSound AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons des bulles produites pour les pas sous de l'eau. movingBubblesSound AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons pour des bulles se déplaçant au travers de l'eau. waterBreathSound AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons de respiration sous l'eau. impactSoftSound AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons d'impacts légers. impactHardSound AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons d'impacts importants. 176 / 223 Description Documentation de Torque V1.3.x Nom Type Valeur par défaut Description impactMetalSound AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons d'impacts contre du métal. impactSnowSound AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons d'impacts contre de la neige. impactWaterEasy AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons d'impacts légers contre de l'eau. impactWaterMedium AudioProfilePtr NULL Si indiqué, doit pointer sur un objet de type AudioProfile. AudioProfile sera utilisé pour produire des sons d'impacts moyens contre de l'eau. impactWaterHard AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons d'impacts importants contre de l'eau. exitingWater AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire un son de sortie d'eau. mediumSplashSoundVelocity Float 2.0 Vitesse minimale à laquelle l'effet d'éclaboussement moyen sera joué lors d'un impact sur l'eau. hardSplashSoundVelocity Float 3.0 Vitesse minimale à laquelle l'effet d'éclaboussement important sera joué lors d'un impact sur l'eau. exitSplashSoundVelocity Float 2.0 Vitesse minimale à laquelle l'effet d'éclaboussement sera joué lors de la sortie de l'eau. Splash SplashDataPtr NULL Si indiqué, doit pointer sur un objet de type SplashData. splashVelocity Float 1.0 Vitesse minimale d'un joueur nécessaire afin de générer un effet d'éclaboussement. splashAngle Float 45 Angle vertical minimal auquel un joueur doit se déplacer afin de générer un effet d'éclaboussement. slashFreqMod Float 300.0 Modulation de fréquence simulée d'un éclaboussement produit par ce joueur. Multiplié avec la vitesse du joueur et le temps passé en déterminant le taux d'émission d'éclaboussure. splashVelEpsilon Float 0.25 Vitesse de seuil auquel nous considérons que le mouvement d'un joueur est arrêté lors de la mise à jour de l'effet d'éclaboussement. bubbleEmitTime Float 0.4 Durée d'émission des bulles. 177 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description splashEmitter ParticleEmitterDataPtr (array) NULL Tableau de pointeurs sur des datablocks ParticleEmitterData qui seront utilisés pour générer les particules d'effet d'éclaboussement. footstepSplashHeight Float 0.1 Hauteur maximale à laquelle jouer l'effet de pas peu profonds. groundImpactMinSpeed Float 10.0 Vitesse minimale à laquelle le joueur doit impacter le sol afin de générer un effet d'impact sur le sol. groupImpactShakeFreq Point3F (10.0, 10.0, 10.0) Fréquence à laquelle secouer la caméra si le joueur est un objet contrôle, et un effet d'impact sur le sol est déclenché. groudImpactShakeAmp Point3F (20.0, 20.0, 20.0) Amplitude à laquelle commencer la secousse de la caméra si le joueur est un objet contrôle, lorsqu'un effet d'impact sur le sol est déclenché. groundImpactShakeDuration Float 1.0 Durée pour secouer la caméra si le joueur est un objet contrôle, et un effet d'impact sur le sol est déclenché. groundImpactShakeFalloff Float 10.0 Amplitude de décroissance pour les effets de secousse de caméra produites lorsque le joueur est un objet contrôle, et un effet d'impact sur le sol est déclenché. Données de restriction de vue minLoOKAngle Float -1.4 Angle minimal de vision de l'utilisateur, en radians. maxLoOKAngle Float 1.4 Angle maximal de vision de l'utilisateur, en radians. maxFreeloOKAngle Float 3.0 Angle gauche/droit maximal de vision de l'utilisateur en mode regard libre, en radians. Données physiques de mouvent d'un joueur runForce Float 360.0 Force physique simulée du joueur lorsqu'il court. Utilisé en accélération de course et en calculs de vitesse. maxForwardSpeed Float 10.0 Vitesse maximale à laquelle le joueur peut courir en avant hors de l'eau. maxBackwardSpeed Float 10.0 Vitesse maximale à laquelle le joueur peut courir en arrière hors de l'eau. maxSideSpeed Float 10.0 Vitesse maximale à laquelle le joueur peut se déplacer sur le côté hors de l'eau. maxUnderwaterForwardSpeed Float 10.0 Vitesse maximale à laquelle le joueur peut courir en avant dans de l'eau. 178 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description maxUnderwaterBackwardSpeed Float 10.0 Vitesse maximale à laquelle le joueur peut courir en arrière dans de l'eau. maxUnderwaterSideSpeed Float 10.0 Vitesse maximale à laquelle le joueur peut se déplacer sur le côté dans de l'eau. maxStepHeight Float 1.0 Hauteur maximale à laquelle le joueur peut monter. runSurfaceAngle Float 80.0 Angle maximal par rapport à la verticale que le joueur sur lequel le joueur peut courir, en degrés. horizMaxSpeed Float 80.0 Vitesse horizontale que le joueur peut atteindre quelque soit le moyen. horizResistSpeed Float 38.0 Vitesse horizontale à laquelle la résistance sera active horizResistFactor Float 1.0 Résistance horizontale subit par le joueur une fois la vitesse horizResistSpeed est atteinte. minImpactSpeed Float 25.0 Vitesse minimale à laquelle un joueur doit se déplacer pour qu'un effet d'impact soit déclenché. recoverDelay Integer 30.0 Nombre d'unités temporelles (ticks) nécessaire pour qu'un joueur se remette d'un impact. recoverRunForceScale Float 1.0 Multiplicateur utilisé pour modifier la force de course du joueur durant la récupération suite à un impact. minJumpSpeed Float 500.0 Vitesse minimale du joueur à laquelle commencer la mesure de la hauteur d'un saut. maxJumpSpeed Float 1000.0 Vitesse maximale à laquelle un joueur peut sauter. La valeur définie sera forcée à une valeur supérieure à minJumpSpeed. jumpSurfaceAngle Float 78.0 Angle par rapport à la verticale en degrés où le joueur peut sauter. jumpDelay Integer 78.0 Délai entre sauts, en unités temporelles (ticks) jumpForce Float 75.0 Force exercée par le joueur pour sauter minJumpEnergy Float 0.0 Énergie minimale requise pour sauter. Note : ce champ peut être supprimé dans le futur. jumpEnergyDrain Float 0.0 Énergie du joueur drainée par un saut. Note : ce champ peut être supprimé dans le futur. 179 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description minRunEnergy Float 0.0 Énergie minimale requise pour courir. Note : ce champ peut être supprimé dans le futur. runEnergyDrain Float 0.0 Énergie du joueur drainée par la course. Note : ce champs peut être supprimé dans le futur. Donnée de boîte d'encadrement (bounding box) boundingBox Point3F (1.0, Ce champ indique la largeur, la 1.0, 2.3) profondeur et la hauteur de la boîte d'encadrement du joueur. boxHeadPercentage Float 0.85 Distance à partir du bas de la boîte d'encadrement du joueur jusqu'au début de la zone considérée comme encadrant la tête du joueur. Ainsi, par défaut, 15 % du haut de la boîte d'encadrement est considéré comme encadrant la tête du joueur. boxTorsoPercentage Float 0.55 Identique à boxHeadPercentage, mais Indique où la zone du torse commence. boxHeadLeftPercentage Integer 0 En conjonction avec boxHeadRightPercentage, utilisé pour déterminer si le côté gauche, central ou droit du torse ou des jambes d'un joueur a été touché. Note : cette fonctionnalité est difficile à modifier correctement ; il est conseillé d'utiliser les valeurs par défaut. boxHeadRightPercentage Integer 1 Voir boxHeadLeftPercentage. boxHeadFrontPercentage Integer 1 En conjonction avec boxHeadBackPercentage, utilisé pour déterminer si le côté avant, central ou arrière du torse ou des jambes d'un joueur a été touché. Note : cette fonctionnalité est difficile à modifier correctement ; il est conseillé d'utiliser les valeurs par défaut. boxHeadBackPercentage Integer 0 Voir boxHeadFrontPercentage. pickupRadius Float 0.0 Rayon autour du joueur pour les éléments (sur le serveur). Lors du test de la valeur, Torque forcera par défaut pickupRadius à ne pas être inférieur au maximun de boundingBox.x et boundingBox.y, mais inférieur à deux fois cette valeur. (pickupRadius >= max(boundingBox.x, boundingBox.y) et <= 2 * max(boundingBox.x, boundingBox.y). Données d'animation 180 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description maxTimeScale Float 1.5 Échelle de temps maximale autorisée pour les animations d'action de joueur. À nouveau, l'implémentation des datablocks basés sur PlayerData est un processus simple identique à celui que nous avons vu pour GameBaseData. Il y a cependant une note importante : Les datablocks PlayerData ne DOIVENT pas avoir une chaîne vide pour le champ shapeField. Si aucune valeur pour shapeFile n'est donnée, Torque produira par défaut une erreur et quittera. Lorsqu'on travaille avec des datablocks PlayerData, il faut toujours fournir une chaîne non vide pour le champ shapeFile, même si c'est seulement une chaîne bidon. Si une chaîne bidon ou un nom de fichier invalide est donné au champ shapeFile du datablock PlayerData, Torque continuera à fonctionner, mais aucune donnée ne sera disponible dans le datablock. Le TGE ne définit aucun datablock dérivé de PlayData. Dans la section suivante, nous jetterons un coup d'œil à une autre dérivation de ShapeBaseData, ItemData. D.5 ItemData Comme PlayerData, ItemData est dérivé de ShapeBaseData et inclut tous les champs définis dans ShapeBaseData. ItemData définit de nouveaux champs, et permet aux développeurs de spécifier rapidement des données relatives aux éléments de base dans le monde du jeu. Comme avec PlayerData, nous listerons seulement les nouveaux champs définis dans ItemData, dans un souci de clarté et de lecture. Voir ShapeBaseData pour plus de détails sur les champs qu'il définit. Nom Type Valeur par défaut Description Données d'éclairage lightType Lightype (enum) NoLight Indique si un éclairage est associé à cet élément ainsi que son type. Les valeurs valides sont NoLight, ConstantLightn, et PulsingLight. Note : tous les éclairages basés sur itemData sont des éclairages Point, ce champ Indique simplement si l'éclairage émet des impulsions ou non. lightColor ColorF (1.0,1.0, 1.0) Couleur d'éclairage de l'objet, si lightType est différent de NoLight. lightRadius Float 10.0 Rayon du point d'éclairage de l'élément. lightOnlyStatic Boolean Flase Indique que seuls les objets statiques doivent être éclairés avec cette lumière. Peut être utilisé qu'avec les éléments statiques. lightTime 1000 Pour le type PulsingLight, la durée de l'impulsion, en unités temporelles (ticks). Integer Données physiques elasticity Float 0.0 Utilisé pour simuler la propriété physique de l'élasticité de la collision d'un objet. Dans les collisions physiques, la vitesse résultante est pondérée par l'élasticité. Valeur entre 0 et 1. friction Float 0.0 Utilisé pour simuler la propriété physique de la friction lors de la collision avec un objet. Dans les collisions physiques, la vitesse résultante est amortie par la pondération de la valeur de friction. Valeur entre 0 et 1. 181 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description sticky Boolean False Utilisé pour forcer l'objet à être collant ; l'élément collera aux objets interior ou terrain qu'il heurtera ; les données retournées dans des méthodes d'objet console telles GetLastStickyPos seront affectées. gravityMod Float -1.0 Indique la vitesse soutenable maximale pour l'objet Champs divers pickUpName String "an item" Peut être utilisé pour indiquer le nom de l'élément à afficher lorsqu'un joueur ramasse un élément. dynamicType Integer 0 Peut être utilisé pour indiquer le type dynamique de l'élément pour son Type Mask. La valeur valide est $TypeMask::DamagableItemObjectType. Dans la prochaine section, nous regarderons quatre datablocks à la fois MissionMarkerData, CameraData, PatchCameraData et StaticshapeData. Nous regroupons ces datablocks dans une unique section, car ils sont tous dérivés de ShapeBaseData, mais ne définissent presque pas de nouveaux champs. 182 / 223 Documentation de Torque V1.3.x D.6 MissionMarkerData, CameraData, PathCameraData et StaticShapeData Dans cette section, nous regarderons rapidement quatre datablocks : MissionMarkerData, CameraData, PatchCameraData et StaticShapeData. Chacun de ces datablocks est dérivé de ShapeBaseData, et MissionMarkerData, CameraData et PatchCameraData ne définissent aucun nouveau champ. StaticShapeData définit seulement deux nouveaux champs. MissionMarkerData, comme son nom l'indique, est employé dans la création des marqueurs de mission (Mission marker), et la classe MissionMarker dans le TGE est utilisée comme base à partir de laquelle sont dérivées les sphères de naissance des joueurs et de point de navigation. Le datablock MissionMarkerData ne définit pas de nouvelle information indépendamment de celles définies dans ShapeBaseData. CameraData ne définit pas également de nouveaux champs à partir de ShapeBaseData, et est simplement destiné à fournir les données de base aux objets de la classe Camera dans le TGE. Il en va de même pour PathCameraData. Les classes StaticShapeData et StaticShape sont utilisées pour créer des formes .dts statiques nécessitant toutes les fonctionnalités de la classe ShapeBase et ses méthodes. Les formes statiques ne nécessitant pas toutes ces fonctionnalités peuvent être créées en utilisant la classe TSStatic. StaticShapeData définit deux nouveaux champs dans TorqueScript, listés dans la table suivante : Nom Type Valeur par défaut Description noIndividualDamage Boolean False Note : actuellement, ce champ n'a aucun d'effet tangible dans la simulation du moteur. dynamicType Integer 0 Peut être utilisé pour indiquer un type dynamique pour le Type Mask de la forme. N'importe quel masque est valide. C'est tout pour cette classe simple de datablock. Dans quelques sections suivantes, nous examinerons les datablocks de la famille VehicleData. 183 / 223 Documentation de Torque V1.3.x D.7 VehicleData VehicleData est dérivé de ShapeBaseData et aide à la création des objets de véhicules. Plusieurs autres datablocks, tels que WheeledVehicleData et FlyingVehicleData sont dérivées de VehicleData. VehicleData définit plusieurs nouveaux champs qui sont listés dans la table ci-dessous : Nom Type Valeur par défaut Description Données d'effets spéciaux softImpactSound AudioProfilePtr NULL Le datablock AudioProfile utilisé pour produire les sons des impacts légers. hardImpactSound AudioProfilePtr NULL Le datablock AudioProfile utilisé pour produire les sons des impacts importants. splashFreqMod Float 300.0 Modulation de fréquence simulée d'éclaboussures produite par ce véhicule. Multiplié avec la vitesse du véhicule et le temps écoulé en déterminant le taux d'émission d'éclaboussures. splashVelEpsilon Float 0.5 Vitesse de seuil à laquelle nous considérons que le mouvement d'un véhicule est arrêté lors de la mise à jour de l'effet d'éclaboussement. splashEmitter ParticleEmitterDataPtr NULL Tableau de pointeurs sur des (array) [VC_NUM_SPLAS datablocks ParticleEmitterData H_EMITTERS] qui seront utilisés pour générer les particules d'effet d'éclaboussement. exitSplashSoundVelocity Float 2.0 Vitesse minimale à laquelle l'effet d'éclaboussement sera joué lors de la sortie de l'eau. softSplashSoundVelocity Float 1.0 Vitesse minimale à laquelle l'effet d'éclaboussement léger sera joué lors d'un impact sur l'eau. mediumSplashSoundVelocity Float 2.0 Vitesse minimale à laquelle l'effet d'éclaboussement moyen sera joué lors d'un impact sur l'eau. hardSplashSoundVelocity Float 3.0 Vitesse minimale à laquelle l'effet d'éclaboussement important sera joué lors d'un impact sur l'eau. exitingWater AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire un son de sortie d'eau. 184 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description impactWaterEasy AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons d'impacts légers contre de l'eau. impactWaterMedium AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons d'impacts moyens contre de l'eau. impactWaterHard AudioProfilePtr NULL Le datablock AudioProfile sera utilisé pour produire des sons d'impacts importants contre de l'eau. waterWakeSound AudioProfilePtr NULL Le datablock AudioProfile utilisé pour produire des sons lorsqu'un sillage est affiché. triggerDustHeight Float 3.0 Hauteur maximale à partir du sol à laquelle le véhicule générera de la poussière. dustHeight Float 1.0 Hauteur de l'effet de poussière. dustEmitter ParticleEmitterDataPtr NULL Tableau de pointeurs vers des (array) [VC_NUM_DUST_ datablocks ParticleEmitterData EMITTERS] utilisés pour émettre des particules au point de contact entre le véhicule et le sol. damageEmitterOffset Point3F (array) (non initialisé) [VC_NUM_DAMA GE_EMITTER_AR EAS] Point d'offset à partir duquel afficher les effets de dommage. Le nombre d'entrées du tableau est limité par la constante VC_NUM_DAMAGE_EMITTER _AREAS dans l'énumération VehicleConsts comme indiqué dans la définition de la classe VehicleData dans le TGE. numDmgEmitterAreas Float 0.0 Nombre de zones sur le véhicule pouvant afficher les effets de dommage. damageEmitter ParticleEmitterDataPtr NULL Tableau de pointeurs vers des (array) [VC_NUM_DAMA datablocks ParticleEmitterData GE_EMITTERS] utilisés pour émettre des particules d'effets de dommage (fumée). Données de caméra cameraRoll Boolean True Indique si la matrice de rotation de caméra, et la transformée du rendu de l'œil sont multipliés durant les mises à jour de la caméra. cameraLag Float 0.0 Quantité scalaire par laquelle la caméra troisième personne est décalée temporellement du véhicule, relatif à la vitesse linéaire du véhicule. 185 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description cameraDecay Float 0.0 Taux scalaire par lequel la caméra troisième personne va décliner, en unités temporelles (ticks). cameraOffset Float 0.0 Offset vertical de la caméra du véhicule Données physiques integration Integer 1 Nombre d'étapes discrètes avec lesquelles les données physiques sont traitées par unité temporelle (tick) minImpactSpeed Float 25.0 Vitesse minimale à laquelle le véhicule doit se déplacer pour que la fonction de script OnImpact soit appelée. softImpactSpeed Float 25.0 Vitesse minimale à laquelle le véhicule doit se déplacer pour que le son d'impact léger soit joué. hardImpactSpeed Float 50.0 Vitesse minimale à laquelle le véhicule doit se déplacer pour que le son d'impact important soit joué. massCenter Point3F (0.00, 0.0, 0.0) Centre de gravité du corps rigide du véhicule. bodyRestituation Float 1.0 Restitution du corps rigide du véhicule. Utilisé dans la simulation physique durant les collisions. La valeur scalaire de restitution affecte la force résultante du rebond du corps des collisions avec des objets. Des valeurs de restitution plus élevées apportent des réactions plus puissantes de rebond. bodyFriction Float 0.0 Coefficient de frottement du corps rigide du véhicule. Utilisé dans la simulation physique durant les contacts et collisions. Des valeurs de frottement plus élevées amortissent des forces de contact et de collision. contactTol Float 0.1 Vitesse minimale de collision requise pour déclencher un contact de collision. Les collisions avec des vitesses inférieures à la valeur contactTol seront traitées comme contraintes de collision. 186 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description collisionTol Float 0.1 damageLevelTolerance Float (array) 0.0 Tableau de flottants indiquant [VC_NUM_DAMA les seuils de niveau de GE_LEVELS] dommage. Chaque entrée est spécifiée comme un pourcentage décimal de maxDomage (défini dans ShapeBaseData). Chaque niveau de dommage est utilisé pour déterminer quel effet de dommage jouer. maxSteeringAngle Float 0.785 Angle de braquage maximal possible mesuré en radians. Les angles de braquage sont limités à cette valeur maximale. minDrag Float 0.0 Action de résistance minimale sur le véhicule à tout moment. À présent, ce champ est utilisé uniquement par FlyingVehicleData et aide à déterminer sa force de déplacement et sa vitesse maximale. maxDrag Float 0.0 Prévu pour limiter la résistance maximale possible. Note : ce champ n'a actuellement aucun d'effet tangible dans la simulation du moteur. jetForce Float 500.0 Force produite par le propulseur du véhicule, s'il en a un. Ce champ est utilisé uniquement par les classes dérivées. jetEnergyDrain Float 0.8 Énergie drainée par unité temporelle (tick) par l'utilisation du propulseur du véhicule, s'il en a un. minJetEntry Float 1.0 Énergie minimale nécessaire pour utiliser le propulseur du véhicule, s'il en a un. collDamageThresholdVel Float 20.0 Note : ce champ n'a actuellement aucun d'effet tangible dans la simulation du moteur. minRollSpeed Float 0.0 Note : ce champ n'a actuellement aucun d'effet tangible dans la simulation du moteur. 187 / 223 Vitesse minimale de collision requise pour déclencher une collision totale. Les collisions avec des vitesses inférieures à la valeur collisionTol seront traitées comme contacts ou contraintes de collision. Documentation de Torque V1.3.x Dans les prochaines sections, nous parlerons des datablocks qui sont dérivés de VehiculeData : FlyingVehicleData, HoverVehiculeData et WheeledVehicleData. 188 / 223 Documentation de Torque V1.3.x D.8 FlyingVehicleData FlyingVehicleData est dérivé de VehicleData et aide à la création des objets de véhicules volants. FlyingVehicleData définit quelques champs en plus listés dans la table suivante : Nom Type Valeur par défaut Description Données d'effets spéciaux jetSound AudioProfilePtr NULL Pointe sur le datablock AudioProfile utilisé pour produire les sons pour le propulseur. engineSound AudioProfilePtr NULL Pointe sur le datablock AudioProfile utilisé pour produire les sons pour le moteur. forwardJetEmitter ParticleEmitterDaraPtr NULL Pointe vers le datablock ParticleEmitterData utilisé pour produire les particules en avant du propulseur. backwardJetEmitter ParticleEmitterDaraPtr NULL Pointe vers le datablock ParticleEmitterData utilisé pour produire les particules en arrière du propulseur. downJetEmitter ParticleEmitterDaraPtr NULL Pointe vers le datablock ParticleEmitterData utilisé pour produire les particules en bas du propulseur. trailEmitter ParticleEmitterDaraPtr NULL Pointe vers le datablock ParticleEmitterData utilisé pour produire les particules de traînée du propulseur. Données physiques maneuveringForce Float 0.0 Force produite par les mouvements dans la direction x ou y (horizontale). Également utilisé pour déterminer la vitesse maximale du FlyingVehicle, par division avec minDrag (défini dans VehicleData. horizontalSurfaceForce Float 0.0 Force d'amortissement des surfaces horizontales du véhicule (ailes) contre sa force de mouvement. verticalSurfaceForce Float 0.0 Force d'amortissement des surfaces verticales du véhicule (dérives) contre sa force de mouvement. rollForce Float 1.0 Force d'amortissement contre les manœuvres de roulement (rotation autour de l'axe y). Affecte le corps rigide du véhicule et sert à ajuster le roulement à une position stable dans le temps. steeringForce Float 1.0 Force produite par le propulseur de direction, affecte le corps rigide du véhicule. 189 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description steeringRollForce Float 1.0 Force de roulement produite par la rotation de la direction. Va contre rollForce qui corrige l'effet de steeringRollForce sur le corps rigide du véhicule. maxAutoSpeed Float 0.0 Vitesse de seuil à laquelle l'assistance de contrôle de véhicule automatique arrête. Les véhicules circulant à une vitesse supérieure à cette valeur n'obtiennent pas d'assistance de contrôle. autoAngularForce Float 0.0 Force angulaire corrective appliquée aux véhicules. Plus la vitesse du véhicule est faible, plus grand est l'effet de autoAngularForce. Affecte le corps rigide du véhicule. autoLinearForce Float 0.0 Force linéaire corrective appliquée uniquement aux véhicules circulant en dessous de maxAutoSpeed (autoAngularForce s'applique aux véhicules volants à n'importe quelle vitesse, mais ses effets augmentent si elle est en dessous de maxAutoSpeed). Affecte le corps rigide du véhicule, et à l'effet de ralentir le véhicule. autoInputDamping Float 1.0 Facteur scalaire par lequel l'entrée de pilotage est amortie lorsque le véhicule circule à des vitesses inférieures à maxAutoSpeed. autoInputDamping est multiplié par le vecteur directionnel du véhicule. vertThrustMultiple Float 1.0 Multiple scalaire appliqué à jetForce (défini dans VehicleData) lors d'une poussée verticale. rotationalDrag Float 0.0 Amortissement scalaire de résistance à la vitesse angulaire du corps rigide du véhicule. hoverHeight Float 2.0 Hauteur du véhicule au repos par rapport au sol. createHoverHeight Float 2.0 Hauteur du véhicule au repos par rapport au sol, lors de sa création. minTrailSpeed Float 1.0 Vitesse minimale à laquelle le véhicule doit circuler afin de générer un nuage. Comme vous venez de le voir, FlyingVehicleData définit un nombre intéressant de nouveaux champs et permet la création facile de véhicules volants avec des caractéristiques de simulation physique robuste. Dans la section suivante, nous regarderons le datablock HoverVehicleData. 190 / 223 Documentation de Torque V1.3.x D.9 HoverVehicleData HoverVehicleData est également dérivé de VehicleData et aide à la création des objets de véhicules à vol stationnaire. HoverVehicleData définit quelques champs en plus listés dans la table suivante : Nom Type Valeur par défaut Description Données d'effets spéciaux jetSound AudioProfilePtr NULL Pointe sur le datablock AudioProfile utilisé pour produire les sons pour le propulseur. engineSound AudioProfilePtr NULL Pointe sur le datablock AudioProfile utilisé pour produire les sons pour le moteur. floatSound AudioProfilePtr NULL Pointe sur le datablock AudioProfile utilisé pour indiquer que le véhicule est en mode stationnaire. dustTrailEmitter ParticleEmitterDataPtr NULL Pointe sur le datablock ParticleEmitterData utilisé dans la génération de particules pour la traînée de poussière du véhicule. dustTrailOffset Point3F (0.0, 0.0, 0.0) Offset à partir duquel générer les particules de poussière à partir du point de contact entre le véhicule et le terrain lorsque le véhicule se déplace. dustTrailFreqMod Float 15.0 Modulation de fréquence utilisée pour émettre de la poussière. triggerTrailHeight Float 2.5 Hauteur maximale au-dessus du sol à laquelle le véhicule commencera à générer une traînée de poussière. Données physiques dragForce Float 0.0 191 / 223 Utilisé pour simuler la résistance constante agissant sur le véhicule. Également utilisé pour déterminer la maxThrustSpeed, ( (mainThrustForce + StrafeThrustForce / dragForce) ). Note : dragForce doit être d'au moins 0.01. Si cela n'était pas le cas, une erreur console se produirait, et le moteur forcerait dragForce à 0.01. Documentation de Torque V1.3.x Nom Type Valeur par défaut Description vertFactor Float 0.25 Scalaire appliqué à la composante verticale de la résistance à la vitesse agissant sur le véhicule. Ce facteur scalaire est appliqué à la vitesse du véhicule qu'il soit en sustentation ou non. Pour la résistance de vélocité pour les composantes x et y, un facteur de 0.25 est appliqué à celles-ci lorsque le véhicule est en sustentation et aucun sinon. Cette résistance de vélocité est multipliée par la dragForce du véhicule, comme définie audessus, et le résultat est soustrait de sa force de mouvement. Note : vertFactor doit être compris entre 0.0 et 1.0 (inclus). Si cela n'est pas le cas, une erreur console sera générée, et la valeur du champ sera limitée. floatingThrustFactor Float 0.15 Facteur scalaire appliqué à la force de poussée du véhicule lorsque le véhicule est en sustentation. Note : floatingThrustFactor doit être compris entre 0.0 et 1.0 (inclus). Si cela n'est pas le cas, une erreur console sera générée, et la valeur du champ sera limitée. mainThrustForce Float 0.0 Force produite en propulsant le véhicule vers l'avant. Également utilisé pour déterminer le volume sonore maximal du moteur (la puissance actuelle de propulsion du véhicule est divisée par mainThrustForce + strafeThrustForce pour la détermination du pourcentage de volume sonore du moteur). Également utilisé pour déterminer la maxThrustSpeed, ((mainThrustForce + StrafeThrustForce) / dragForce). Note : dragForce doit être d'au moins 0.01. Si cela n'était pas le cas, une erreur console se produirait, et le moteur forcerait dragForce à 0.01. reverseThrustForce Float 0.0 Force produite en propulsant le véhicule en arrière. 192 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description strafeThrustForce Float 0.0 Force produite en propulsant le véhicule sur le côté. Également utilisé pour déterminer le volume sonore maximal du moteur (la puissance actuelle de propulsion du véhicule est divisée par mainThrustForce + strafeThrustForce pour la détermination du pourcentage de volume sonore du moteur). Également utilisé pour déterminer la maxThrustSpeed, ( (mainThrustForce + StrafeThrustForce) / dragForce). Note : dragForce doit être d'au moins 0.01. Si cela n'était pas le cas, une erreur console se produirait, et le moteur forcerait dragForce à 0.01. turboFactor Float 1.0 Facteur par lequel la force de propulsion du véhicule est multipliée lors de la mise en service du mode turbo. normalForce Float 30.0 floatingGravMag Float 1.0 Facteur par lequel la force gravitationnelle affectant le véhicule est altérée lorsque le véhicule est en sustentation. brakingForce Float 1.0 Force produite en freinant (le véhicule est considéré comme freinant si la commande de puissance est éteinte, et qu'aucune propulsion gauche ou droite n'est appliquée, mais que le véhicule se déplace). brakingForce est appliqué seulement lorsque la vitesse du véhicule est inférieure à brakingActivationSpeed, défini après. brakingActivationSpeed Float 0.0 Vitesse maximale à laquelle le véhicule peut se déplacer afin que la brakingForce soit appliquée. gyroDrag Float 10.0 La résistance gyroscopique qui est appliquée contre la vitesse angulaire du véhicule pour limiter le couple du corps rigide. restorativeForce Float 10.0 193 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description steeringForce Float 25.0 Force appliquée aux manœuvres de pilotage (rotation autour de l'axe z) le long de l'axe x ; affecte le couple du corps rigide du véhicule. rollForce Float 2.5 Force de roulement (rotation autour de l'axe y) appliqué en s'orientant dans la direction x. pitchForce Float 2.5 Force de tangage (rotation autour de l'axe x) appliquée aux manœuvres de pilotage le long de l'axe y. stabLenMin Float 0.5 stabLenMax Float 2.0 stabSpringConstant Float 30.0 Valeur utilisée pour produire la force d'élévation, contre la compression du stabilisateur. stabDampingConstant Float 10.0 Scalaire utilisé pour déterminer la force d'amortissement agissant contre la force d'élévation du véhicule. HoverVehicleData fournit de nombreux nouveaux champs, et l'opportunité de simulations physiques complexes. Dans la prochaine section, nous examinerons WheeledVehicleData. 194 / 223 Documentation de Torque V1.3.x D.10 WheeledVehicleData WheeledVehicleData est dérivé de VehicleData et aide à la création des objets de véhicules avec des roues et des pneus. WheeledVehicleData définit peu de nouveaux champs contrairement à FlyingVehicleData et HoverVehicleData ; ces nouveaux paramètres sont listés dans la table suivante : Nom Type Valeur par défaut Description Données d'effets spéciaux jetSound AudioProfilePtr NULL Pointe sur le datablock AudioProfile utilisé pour produire les sons pour le propulseur. engineSound AudioProfilePtr NULL Pointe sur le datablock AudioProfile utilisé pour produire les sons pour le moteur. squealSound AudioProfilePtr NULL Pointe sur le datablock AudioProfile utilisé pour produire les sons de crissement des pneus. wheelImpactSound AudioProfilePtr NULL Note : ce champ actuellement n'a aucun effet tangible dans la simulation du jeu. tireEmitter ParticleEmitterDataPtr 0 Pointe sur le datablock ParticleEmitterData utilisé pour chaque objet ParticleEmitter des roues (chaque roue a son propre ParticleEmitter). Données physiques maxWheelSpeed Float 40.0 Détermine la vitesse maximale à laquelle le véhicule peut circuler. Affecte également la durée de vie des particules émises par la roue. engineTorque Float 1.0 Scalaire appliqué à la valeur de commande de puissance du véhicule pour la détermination du couple moteur total et la vitesse angulaire de la roue. engineBrake Float 1.0 Utilisé pour déterminer la vitesse d'amortissement affectant la vitesse angulaire d'une roue lorsque le véhicule utilise le frein moteur (pas d'activation des freins, et aucune poussée appliquée). Plus de données supplémentaires pour les véhicules à roues sont définies dans les datablocks WheeledVehicleTire et WheeledVehicleSpring, qui sont détaillés plus tard. Nous avons terminé l'examen de tous les datablocks dérivés de ShapeBaseData. Dans la prochaine section, nous retournerons à l'étude des autres datablocks dérivés de GameBaseData, en commençant par TriggerData. 195 / 223 Documentation de Torque V1.3.x D.11 TriggerData Nous avons fini de détailler les datablocks dérivés de ShapeBaseData, et retournons maintenant à la famille GameBaseData. Le datablock TriggerData est un des plus couramment utilisés dans Torque. Les déclencheurs fournissent un moyen commode et automatique pour effectuer des actions en réponse au comportement des joueurs. TriggerData est assez simple. Il dérive de GameBaseData et en a les champs standards category et className. Nom Type tickPeriodMS Integer Valeur par défaut Description 100 Fréquence, en millisecondes, à laquelle mettre à jour le comportement du déclencheur (trigger), jusqu'à ce qu'il soit actif. Le déclencheur est actif si, et seulement si, un objet dérivé de GameBase est à l'intérieur de lui. L'unique champ de TroggerData fournit toutes les données nécessaires pour créer un déclencheur comportemental fonctionnel dans une application Torque. Bien sûr, les opérations à effecteur, lorsque le déclencheur est actif, doivent également être fournies. Dans la section suivante, nous examinons le datablock ProjectileData. 196 / 223 Documentation de Torque V1.3.x D.12 ProjectileData ProjectileData est dérivé de GameBaseData et est utilisé pour fournir le rendu, le comportement et les données physiques des objets Projectile. La table suivante détaille les champs de ProjectileData. Dans un souci de clarté, nous continuerons à omettre les deux champs (category et className) dont les enfants de GameBaseData héritent. Nom Type Valeur par défaut Description Données d'effets spéciaux particleEmitter ParticleEmitterDaraPtr NULL Pointe vers le datablock ParticleEmitterData utilisé pour produire des particules pour le projectile quand il est hors de l'eau, et lorsqu'il entre ou sort de l'eau. particleWaterEmitter ParticleEmitterDaraPtr NULL Pointe vers le datablock ParticleEmitterData utilisé pour produire des particules pour le projectile quand il est sous l'eau, et lorsqu'il entre ou sort de l'eau. explosion ExplosionDataPtr NULL Pointe vers le datablock ExposionData utilisé lorsque l'objet Projectile explose hors de l'eau. waterExplosion ExplosionDataPtr NULL Pointe vers le datablock ExposionData utilisé lorsque l'objet Projectile explose dans l'eau. sound AudioProfilePtr NULL Pointe vers le datablock AudioProfile utilisé pour produire les sons de l'objet Projectile. splash SplashDataPtr NULL Pointe vers le datablock SpashData utilisé pour produire l'effet d'éclaboussement lorsque le Projectile entre ou sort de l'eau. decal DecalDataPtr (array) NULL Tableau de pointeurs sur des datablocks [NumDecals] DecalData. Un objet decal non-NULL sera choisi aléatoirement dans le tableau lorsque le Projectile heurtera le terrain ou un interior. Données de rendu projectileShapeName Filename NULL Nom du fichier de forme de l'objet Projectile. hasLight Boolean False Indique si l'objet Projectile projette de la lumière lorsqu'il n'est pas dans l'eau. Si c'est le cas, un objet de point lumière est utilisé avec le rayon et la couleur spécifiés par les champs lightRadius et lightColor. hasWaterLight Boolean False Indique si l'objet Projectile projette de la lumière lorsqu'il est dans l'eau. Si c'est le cas, un objet de point lumineux est utilisé avec le rayon et la couleur spécifiés par les champs lightRadius et lightColor. lightRadius Float 1.0 Rayon du point lumineux du projectile. Valeur valide entre 1.0 et 20.0. lightColor ColorF (1.0, 1.0, 1.0) Couleur du point lumineux du projectile pour utiliser hors de l'eau. 197 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description waterLightColor ColorF (1.0, 1.0, 1.0) Couleur du point lumineux du projectile pour utiliser dans l'eau. Scale Point3F (1.0, 1.0, 1.0) Échelle de transformation de rendu a appliqué à la forme, respectivement, le long des axes x, y et z. Données comportementale lifetime Integer 62 Nombre d'unités temporelles (ticks) durant lesquelles le projectile doit survivre. Également utilisé avec fadeDelay pour déterminer la transparence de l'objet Projectile à un temps donné. Voir la documentation du champ fadeDelay pour plus d'information. Valeur valide entre 0 et Projectile::MaxLivingTicks (4095 par défaut). armingDelay Integer 0 Nombre d'unités temporelles (ticks) devant passer après la création du Projectile avant qu'il puisse exploser. Valeur valide entre 0 et Projectile::MaxLivingTicks (4095 par défaut). fadeDelay Integer 62 Nombre d'unités temporelles (ticks) devant passer après la création du Projectile avant qu'il commence à devenir transparent. L'opacité du Projectile suivra une dégression linéaire commençant avec un nombre de ticks (fadeDelay) après la création et finissant à la durée de vie. Valeur valide entre 0 et Projectile::MaxLivingTicks (4095 par défaut). Données physiques isBallistic Boolean False Indique si le Projectile sera affecté par la gravité, et s'il peut rebondir avant d'exploser. velInheritFactor Float 1.0 Note : ce champ n'a actuellement aucun effet tangible dans la simulation, mais il est utile dans les scripts. Valeur valide entre 0.0 et 1.0. muzzleVelocity Float 50.0 Note : ce champ n'a actuellement aucun effet tangible dans la simulation, mais il est utile dans les scripts. Valeur valide entre 0.0 et 10000.0. bounceElasticity Float 0.999 Utilisé pour simuler l'élasticité du rebond du Projectile, s'il heurte quelque chose, mais n'explose pas. L'élasticité de rebond agit sur la vitesse du rebond, après que le frottement ait été pris en compte. Valeur valide entre 0.0 et 0.999. gravityMod Float 1.0 Si isBallistic est true, agit sur l'effet de la gravité sur le Projectile. Valeur valide entre 0.0 et 1.0. Dans la section suivante, nous examinons DebrisData, qui est aussi dérivé de GameBaseData. 198 / 223 Documentation de Torque V1.3.x D.13 DebrisData Les datablocks DebrisData sont utilisés pour fournir des données aux objets Debris, qui sont des formes simples dans le monde qui ne nécessite pas toutes les fonctionnalités des formes dérivées de ShapeBaseData, et qui ont quelques caractéristiques uniques, comme une durée de vie limitée, et des comportements de rebond spécifiques. Les objets Debris peuvent émettre des particules et produire des explosions. DebrisData est dérivé de GameBaseData. Nom Type Valeur par défaut Description Données d'effets spéciaux texture String NULL Texture utilisée pour l'objet de débris. shapeFile Filename NULL Nom du fichier de forme utilisé pour l'objet de débris. render2D Boolean False Indique si on doit afficher un panneau d'indication pour l'objet de débris. Données d'effets spéciaux emitter ParticleEmitterDataPtr NULL Tableau de pointeurs sur des (array) [DDC_NUM_EMIT datablocks ParticleEmitterData qui TERS] seront utilisés pour produire des effets de particules. explosion ExplosionDataPtr NULL Pointe sur le datablock qui indiquera l'effet d'explosion à utiliser si l'objet débris explose. Données physiques elasticity Float 0.3 Utilisé pour simuler la propriété physique de l'élasticité d'un objet lors du calcul du rebond ; plus grande est l'élasticité, plus grande sera la vitesse résultante du rebond. Affecte aussi l'angle de rotation des objets de débris. Si le champ useRadiusMass est à true, la valeur de frottement, utilisée dans le calcul de la vitesse du rebond et l'angle de rotation, est aussi affectée par la valeur baseRadius ; pour plus d'information, voir la documentation de ces champs. Si la valeur est supérieure à 10.0, ou inférieure à -10.0, un avertissement console sera généré et la valeur forcée à 0.2. friction Float 0.2 Utilisé pour simuler la propriété physique de frottement lors du rebond d'un objet de débris. La vitesse de rebond résultante est amortie avec la valeur de frottement. Si le champ useRadiusMass est à true, la valeur de frottement, utilisée dans le calcul de la vitesse de rebond, est également affectée par la valeur baseRadius. 199 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description useRadiusMass Boolean False Indique si la valeur baseRadius affectera ou non les valeurs de frottement, d'élasticité et d'angles de rotation des objets de débris. baseRadius Float 1.0 Si le champ useRadiusMass est à true, indique la valeur maximale du champ radius de l'objet de débris pour laquelle valeur les calculs standards d'élasticité, de frottement et de rotation s'appliquent. Si le champ radius de l'objet de débris est supérieur à la valeur spécifiée dans baseRadius, et le champ useRadiusMass à true, alors les valeurs d'élasticité, de frottement et de rotation sont amorties en les affectant avec (baseRadius / radius). minSpinSpeed Float 0.0 Un objet Debris utilisant le datablock aura une vitesse de rotation basée sur un nombre aléatoire entre minSpinSpeed et maxSpinSpeed. Si la valeur de minSpinSpeed est inférieure à -10000.0, supérieure 10000.0 ou supérieure à maxspinSpeed, un avertissement console sera généré et les valeurs de minSpinSpeed et maxSpinSpeed seront forcées à -1.0. maxSpinSpeed Float 0.0 Voir minSpinSpeed. gravModifier Float 1.0 Valeur par laquelle l'effet de la force de gravité est affecté. Une valeur à 1.0 signifie aucune modification de la force gravitationnelle par défaut. terminalVelocity Float 0.0 Vitesse maximale à laquelle le débris se déplace. Si la valeur indiquée est inférieure ou égale à 0.0001, elle est ignorée. velocity Float 0.0 Utilisé avec velocityVariance pour déterminer la vitesse initiale de l'objet de débris. velocityVariance Float 0.0 Utilisé avec velocity pour déterminer la vitesse initiale de l'objet de débris. Un nombre aléatoire sera généré entre (-1*velocityVariance) et velocityVariance, et sera ajouté à velocity pour déterminer la vitesse initiale de l'objet Debris. Cela signifie que les multiples objets Debris partageant le même datablock DebrisData ne doivent pas avoir la même vitesse initiale. 200 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description lifeTime Float 3.0 Utilisé avec lifetimeVariance pour déterminer combien de temps l'objet Debris persistera dans le monde. Si la valeur est inférieure à 0.0, ou supérieure à 1000.0, un avertissement console sera généré et la valeur sera forcée à 3.0. lifetimeVariance Float 0.0 Utilisé avec lifetime pour déterminer combien de temps l'objet Debris persistera dans le monde. Si la valeur est inférieure à 0.0, ou supérieure à la valeur de lifetime, un avertissement console sera généré et la valeur sera forcée à 0.0. Données comportementale numBounces Integer 0 Avec bounceVariance, détermine le nombre maximal de rebonds que l'objet Debris peut effectuer. Si la valeur est inférieure à 0, ou supérieure à 1000 un avertissement console sera généré et la valeur sera forcée à 3. bounceVariance Integer 0 Utilisé en conjonction avec numBounces pour déterminer le nombre maximal de rebonds que l'objet Debris peut effectuer. Le nombre maximal de rebonds est déterminé en ajoutant numBounces avec un nombre aléatoire généré entre (-1*bounceVariance) et bounceVariance. Ainsi, un datablock DebrisData avec une valeur bounceVariance à 0 signifie que tous les objets de débris ne rebondiront pas plus de numBounces fois. Indiquer une valeur de boundeVariance non nulle indiquera que les multiples objets Debris partageant le même datablock DebrisData n'auront pas le même nombre de rebonds. Si bounceVariance est inférieure à 0, ou supérieure à la valeur du champ numBounces, un avertissement console sera généré et bounceVariance sera forcée à 0. explodeOnMaxBounce Boolean False Indique si l'objet Debris explosera après le nombre de rebonds maximal. staticOnMaxBounce Boolean False Indique si l'objet Debris sera statique après le nombre de rebonds maximal. snapOnMaxBounce Boolean False Indique si l'objet Debris se cassera dans position une plate après le nombre de rebonds maximal. ignoreWater Boolean True Indique si l'objet Debris doit rebondir sur l'eau. 201 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description fade Boolean True Indique si l'objet Debris commencera à s'atténuer lorsque sa durée de vie arrivera vers la fin. Le comportement pas défaut est une progression linéaire de transparence, une seconde avant la fin de la durée de vie. Le tableau ci-dessus montre les champs de DebrisData permettant une spécification de comportements variés, même lorsque les objets Debris partagent le même datablock. Les objets Debris sont tout à fait utiles pour les formes de base qui peuvent rebondir, ou qui ne doivent durer que pendant la période indiquée. 202 / 223 Documentation de Torque V1.3.x D.14 SplashData Comme avec DebrisData, les datablocks SplashData sont dérivés de GameBaseData, et définissent des champs utiles pour quelques fonctionnalités spéciales. Dans ce cas, SplashData, sans surprise, est conçu pour permettre la configuration rapide des données relatives aux objets Splash. Nom Type Valeur par défaut Description Données d'effets spéciaux soundProfile AudioProfilePtr NULL Note : ce champ n'a actuellement aucun effet tangible. explosion ExplosionDataPtr NULL Pointe vers le datablock ExposionData qui sera pour produire une explosion pour l'éclaboussement. emitter ParticleEmitterDataPtr NULL Tableau de pointeurs sur des datablocks (array) [DDC_NUM_EMIT ParticleEmitterData qui indiquent l'émission de TERS] particules à utiliser pour l'objet Splash. Données d'effets de rendu colors ColorF (array) (1.0, 1.0, 1.0, 1.0) Tableau de couleurs. Indique quelles couleurs [NUM_TIME_KEY sont utilisées pour les anneaux S] d'éclaboussement à chacune des valeurs de temps indiquées dans le tableau du champ times. La première entrée dans le tableau colors correspond à la couleur l'anneau initial, et est interpolée avec colors[1] jusqu'à ce que le temps times[0] soit dépassé, et commence l'interpolation avec colors[2]. times Float (array) [0.0, 1.0, ..., 1.0] Tableau de valeurs de temps. Chaque entrée [NUM_TIME_KEY est utilisée pour déterminer la couleur utilisée S] dans le rendu des anneaux d'éclaboussure, comme d'écrit dans la description du champ colors. texture Filename textWrap Float numSegment Integer s Fichier de texture à utiliser pour les anneaux d'éclaboussement. 1.0 Valeur scalaire utilisée avec numSegments pour déterminer la valeur de coordonnée u de texture, lue à partir du fichier de texture des anneaux d'éclaboussement, durant leurs rendus. 10 Nombre de segments utilisés pour produire chaque anneau d'éclaboussement. Chaque segment a une coordonnée u de texture d'anneau d'éclaboussement associé, qui est calculé en divisant la position du segment dans la liste des segments des anneaux par le nombre total d'anneaux, et ensuite, en multipliant ce résultat par la valeur scalaire du champ textWrap. 203 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description textFactor Float 3.0 Valeur scalaire utilisée pour déplacer la valeur de la coordonnée v de texture, lue dans le fichier de texture des anneaux d'éclaboussement, durant leurs rendus. textFactor n'est pas appliqué directement à la coordonnée v, comme l'est le champ textWrap. À la place, textFactor est multiplié avec la portion non entière du temps écoulé (INT(elapsedTime)) pour déterminer la position de la coordonnée v de texture. Données comportementale lifetimeMS Integer 1000 Utilisé avec lifetimeVariance pour déterminer le temps maximal de persistance de l'objet Splash dans le monde. Mesuré en millisecondes entières. lifetimeVarian Integer ce 0 Utilisé avec lifetimeMS pour déterminer le temps maximal de persistance de l'objet Splash dans le monde. La durée de vie actuelle de l'objet Splash est calculée en ajoutant le champ lifetimeMS avec un nombre aléatoire sera généré entre -1*lifetimeVariance et lifetimeVariance. Un objet Splash sera marqué comme mort une fois que sa durée de vie aura expirée, mais un objet Splash ne se détruira pas lui-même jusqu'à ce que la durée de vie de ses anneaux n'aura pas expirée. En utilisant des lifetimeVariance, des objets Splash séparées partageant le même bloc de donénes SplashData peut donner des comportements variés. ringLifetime Float 1.0 Durée de vie, en secondes des anneaux d'éclaboussement produit par l'objet Splash. Aussi utilisé durant le rendu des anneaux pour déterminer l'opacité de l'anneau ; l'anneau de départ est complètement transparent, et suit une progression linéaire pour devenir complètement opaque au point médian de sa durée de vie, après quoi une décroissance linéaire dans de l'opacité survient jusqu'à la fin de la durée de vie de l'anneau, à ce point l'anneau est à nouveau entièrement transparent. Un objet Splash ne se détruira pas lui-même jusqu'à ce que tous les anneaux qu'il a produits aient expiré. delayMS Integer 0 Note : ce champ n'a actuellement aucun effet tangible. delayVarianc e Integer 0 Note : ce champ n'a actuellement aucun effet tangible. scale Point3F (1.0, 1.0, 1.0) Note : ce champ n'a actuellement aucun effet tangible. Données physiques 204 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description velocity Float 5.0 Vitesse d'éclaboussement, telle qu'utilisée dans la simulation. Affecte le rayon de l'éclaboussement dans le temps, et la vitesse des anneaux. La vitesse change au cours du temps en accord avec la valeur indiquée dans le champ acceleration, et la gravité affectant la simulation physique. acceleration Float 0.0 Accélération de l'éclaboussement, telle qu'utilisée dans la simulation. Affecte la vitesse de l'éclaboussement dans le temps, avec la force de gravité agissant dans le système. ejectionFreq Float 5.0 Fréquence à laquelle les nouveaux anneaux d'éclaboussement devront être créés. ejectionAngle Float 45.0 Angle auquel les nouveaux anneaux d'éclaboussement devront être éjectés, indiqué en degrés. startRadius Float 1.0 Rayon initial auquel éjecter les anneaux d'éclaboussement, affecté par la vitesse au cours du temps. width Float 4.0 Note : ce champ n'a actuellement aucun effet tangible. height Float 0.0 Note : ce champ n'a actuellement aucun effet tangible. Les datablocks SplashData fournissent aux développeurs la possibilité de spécifier rapidement des données relatives au comportement des effets d'éclaboussement. Comme avec DebrisData, des comportements divers peuvent être produits à partir des objets qui partagent le même datablock. Dans la section suivante, nous examinons le datablock LightningData. 205 / 223 Documentation de Torque V1.3.x D.15 LightningData LightningData également dérivé de GameBaseData, est utilisé par les objets Lightning pour produire des effets d'éclair assez sophistiqués. Bien que les effets d'éclair du TGE sont robustes, le datablock LightningData lui-même est assez simple ; ses champs sont détaillés dans la table suivante : Nom Type Valeur par défaut strikeProfile AudioProfilePtr NULL Description Pointe sur le datablock AudioProfile utilisé pour produire les sons pour les coups de tonnerre. thunderSounds AudioProfilePtr NULL Tableau de pointeurs sur AudioProfile utilisé pour (array) [MaxThunders] produire les sons pour les coups de tonnerre. strikeTextures String (array) [MaxTextures] Tableau de noms de texture a utiliser lors du rendu des coups de tonnerre. Actuellement, le moteur utilise uniquement le premier des noms fournis. Comme vous pouvez le voir, le datablock LightningData est simple. Cependant, Torque dupporte à merveille les fonctionnalités des éclairs, comme cela peut être vu dans plusieurs tutoriels et guides pour Torque ou l'éditeur de mission. Le moteur gère simplement de lui-même, sans nécessiter beaucoup de données d'un datablock. Dans la section suivante, nous examinons un autre datablock relatif au climat, PrecipitationData. 206 / 223 Documentation de Torque V1.3.x D.16 PrecipitationData PrecipitationData dérive aussi de GameBaseData, et est un autre datablock climatique. Pour le moment, le code de Precipitation du moteur est assez opaque, et peut évoluer dans le futur. Ainsi, la documentation pour ce datablock est très clairsemé et beaucoup moins complet que pour les autres datablocks dans ce document. Les champs sont simplement listés ci-dessous pour référence. Nom Type Valeur par défaut Description soundProfile AudioProfilePtr NULL type Integer 0 maxSize Float 1.0 materialList String NULL sizeX Float 1.0 sizeY Float 1.0 movingBoxPer Float (non initialisé) divHeightVal Float (non initialisé) sizeBigBox Float (non initialisé) topBoxSpeed Float (non initialisé) frontBoxSpeed Float (non initialisé) topBoxDrawPer Float (non initialisé) bottomDrawHeight Float (non initialisé) skipIfPer Float (non initialisé) bottomSpeedPer Float (non initialisé) frontSppedPer Float (non initialisé) frontRadiusPer Float (non initialisé) Pointe sur le datablock AudioProfile utilisé pour produire les précipitations De nouveau, cette documentation est incomplète, car le code de Precipitation peut évoluer. Dans la prochaine section, nous examinons ExplosionData. 207 / 223 Documentation de Torque V1.3.x D.17 ExplosionData PrecipitationData dérive aussi de GameBaseData, ses champs peuvent être utilisés pour créer des effets d'explosion impressionnants impliquant des particules, des débris, des formes dts, des sons et des secousses de caméra. De multiples objets d'explosion partageant le même datablock peuvent être construits pour exposer divers comportements, avec des datablocks DebrisData et SplashData. Le tableau suivant liste chaque champ de ExplosionData, accompagné d'une description détaillée. Nom Type Valeur par défaut Description Données d'effets spéciaux soundProfile AudioProfilePtr NULL Pointe sur le datablock AudioProfile utilisé pour produire les sons de l'explosion. particleEmitter ParticleEmitterDaraPtr NULL emitter ParticleEmitterDaraPtr NULL Tableau de pointeurs sur des (array) [EC_NUM_EMITT datablocks ParticleEmitterData utilisés ERS] dans la génération de particules pour l'explosion au cours du temps. Debris DebrisDataPtr (array) 0 Tableau de pointeurs sur des [EC_NUM_DEBRI datablocks DebrisData utilisés dans la S_TYPES] génération de débris lorsque l'explosion survient. Notez qu'il y aura de multiples objets de débris créés pour une entrée dans le tableau Debris ; le nombre d'objets de débris créé est déterminé par la valeur des champs debrisNum et debrisNumVariance. subExplosion ExplosionDataPtr (array) 0 Tableau de pointeurs sur des [EC_MAX_SUB_E datablocks ExplosionData utilisés dans XPLOSIONS] la génération de sous-explosion lorsque l'explosion survient. shockwave ShockwaveDataPtr NULL Pointe vers le datablock ParticleEmitterData utilisé pour produire des particules lorsque la première explosion survient. particleEmitter est détruit une fois que son nombre de particules atteint 0. Note : ce champ n'a actuellement aucun effet tangible. La classe ShockWaveDat et uniquement nommée, mais pas encore développée, dans le moteur. Données de rendu playSpeed Float 1.0 208 / 223 Vitesse à laquelle jouer l'animation des formes de l'animation. La valeur doit être supérieure ou égale à 0.05. Note : l'actuel playSpeed utilisé n'est garanti d'être précis uniquement à +/- 0.05 de la valeur indiquée. Documentation de Torque V1.3.x Nom Type Valeur par défaut Description explosilonScale Point3F (1.0, 1.0, 1.0) Contient les facteurs d'échelle x, y, et z pour la taille de l'explosion. Note : l'actuel explosionScale utilisé n'est garanti d'être précis uniquement à +/0.01 de la valeur indiquée. Chacune des valeurs ne doit pas être inférieure à 0.01, sinon un avertissement console est généré et les valeurs incorrectes seront forcées à 0.01. faceViewer Boolean False Indique si la dorme d'explosion doit être orientée vers la caméra. lightStartRadius Float 0.0 Rayon du point lumineux utilisé au début de l'explosion. Si la valeur est nulle à la fois pour lightStartRadius et lightEndRadius, aucune lumière ne sera produite par l'explosion. lightEndRadius Float 0.0 Rayon du point lumineux utilisé à la fin de l'explosion. Le rayon suit une progression linéaire allant de lightStartRadius à lightEndRadius. Si la valeur est nulle à la fois pour lightStartRadius et lightEndRadius, aucune lumière ne sera produite par l'explosion. lightStartColor ColorF (1.0, 1.0, 1.0) Couleur du point lumineux utilisé au début de l'explosion. lightEndColor ColorF (1.0, 1.0, 1.0) Couleur du point lumineux utilisé à la fin de l'explosion. Données comportementale times Float (array) [0.0, 1.0, ..., 1.0] Tableau de pourcentage représentant [EC_NUM_TIME_ les seuils temporels auxquels la taille KEYS] de l'explosion change. Chacune des entrées doit être comprise entre 0.0 et 1.0. Si une valeur est supérieure à 1.0, toutes les entrées suivantes du tableau sont ignorées. Les entrées doivent être données dans l'ordre ascendant, si une entrée a une valeur inférieure à la précédente, elle est ignorée. 209 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description sizes Point3F (array) (1.0, 1.0, 1.0) Chaque entrée contient un facteur [EC_NUM_TIME_ d'échelle x, y, et z pour la taille de KEYS] l'explosion. La taille de l'explosion commence à size[0] (avec chaque composante affectée par les valeurs x, y, et z de explosionScale). Au fil du temps, la taille est interpolée linéairement vers size[i] (également affectée par explosionScale) de telle sorte que size[1] soit atteinte lorsque time[1] % de la durée de vie de l'explosion est atteinte. À partir de là, la taille est interpolée entre size[1] et size[2] (chacune affectée par explosionScale), et ainsi de suite. Note : les sizes actuelles sont garanties d'être précises uniquement à +/- 0.01 de la valeur indiquée. Chaque composante est limitée entre 0.0 et 160.0. lifetimeMS Integer 1000 210 / 223 Utilisé avec lifetimeVariance pour déterminer la durée de vie de l'explosion, mesurée en millisecondes. La durée de vie totale est utilisée pour régler l'échelle d'interpolation pour la taille et les couleurs de l'explosion au cours du temps. Pour préserver la bande passante du réseau, la valeur de lifetimeMS est décalée de 5 bits à bits, impliquant une perte de précision. Cependant, la durée de vie utilisée peut être inférieure de 31 millisecondes que la valeur indiquée. Après le décalage, la valeur est limitée à 16 bits de précision ; cependant, les valeurs de plus de 35 minutes ne se comporteront pas comme prévu. Documentation de Torque V1.3.x Nom Type Valeur par défaut Description lifetimeVariance Integer 0 Utilisé avec lifetimeMS pour déterminer la durée de vie totale de l'explosion. Un nombre aléatoire entre -1*lifetimeVariance et lifetimeVariance est généré, et il est ajouté à la valeur du champ lifetimeMS pour arriver à la durée de vie totale de l'explosion. Cependant, les explosions utilisant le même datablock ExplosionData peuvent avoir des comportements variés. Comme le champ lifetimeMS, lifetimeVariance est en millisecondes. La valeur indiquée ne doit pas être supérieure que celle du champ lifetimeMS, sinon un avertissement console sera généré et la valeur sera forcée à la valeur de lifetimeMS. La valeur delayMS est décalée de 5 bits vers la droite et limitée à 16 bits de précision, exactement comme le champ lifetimeMS. DelayMS Integer 0 Utilisé avec delayVariance pour déterminer le nombre de millisecondes à attendre avant l'explosion. La valeur ne doit pas être négative, sinon un avertissement console sera généré et la valeur mise à 0. La valeur delayMS est décalée de 5 bits vers la droite et limitée à 16 bits de précision, exactement comme le champ lifetimeMS. DelayVariance Integer 0 Utilisé avec delayMS pour déterminer le nombre de millisecondes à attendre avant l'explosion. Un nombre aléatoire entre -1*delayVariance et delayVariance est généré, et il est ajouté à la valeur du champ delayMS pour déterminer le délai total avant l'explosion. La valeur ne doit pas être supérieure à delayMS, sinon un avertissement console sera généré et la valeur sera forcée à la valeur de delayMS. La valeur delayVariance est décalée de 5 bits vers la droite et limitée à 16 bits de précision, exactement comme le champ lifetimeMS. 211 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description offset Float 0.0 Valeur scalaire qui est multipliée par un vecteur normalisé aléatoire avec les entrées x: [-1.0, 1.0], y: [0.0, 1.0] et z: [-1.0, 1.0], et le résultat est utilisé pour ajuster l'orientation et la position initiale du vecteur. Cependant, les explosions partageant le même datablock peuvent avoir des positions et des orientations variées. La valeur indiquée ne doit pas être négative, sinon un avertissement console sera généré et la valeur sera forcée à 0. Les valeurs inférieures à 0.001 sont ignorées. particleDensity Integer 10 Densité initiale de particules à utiliser, particleDensity indique le nombre de particules à produire et à répartir dans l'hémisphère ParticleEmitter du champ particleEmitter. La valeur a une précision de 14 bits. particleRadius Float 1.0 Rayon utilisé par le datablock ParticleEmitterData du champ particleEmitter. debrisThetaMin Float 0.0 Indique la limite basse de la gamme des angles d'éjection des débris par rapport à l'axe x. Si l'explosion éjecte des débris, ils seront éjectés avec un angle theta aléatoire (suivant l'axe x) entre debrisThetaMin et debrisThetaMax, mesuré en degrés. La valeur doit être comprise entre 0 et debrisThetaMax. debrisThetaMax Float 90.0 Indique la limite haute de la gamme des angles d'éjection des débris par rapport à l'axe x. Si l'explosion éjecte des débris, ils seront éjectés avec un angle theta aléatoire (suivant l'axe x) entre debrisThetaMin et debrisThetaMax, mesuré en degrés. La valeur doit être comprise entre 0 et 180. debrisPhiMin Float 0.0 Indique la limite basse de la gamme des angles d'éjection des débris par rapport à l'axe z. Si l'explosion éjecte des débris, ils seront éjectés avec un angle phi aléatoire (suivant l'axe x) entre debrisPhiMin et debrisPhiMax, mesuré en degrés. La valeur doit être comprise entre 0 et debrisPhiMax. 212 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description debrisPhiMax Flota 360.0 Indique la limite haute de la gamme des angles d'éjection des débris par rapport à l'axe z. Si l'explosion éjecte des débris, ils seront éjectés avec un angle phi aléatoire (suivant l'axe x) entre debrisPhiMin et debrisPhiMax, mesuré en degrés. La valeur doit être comprise entre 0 et 360. debrisNum Integer 1 Utilisé avec debrisNumVariance pour déterminer le nombre d'objets Debris que l'explosion émettra. La valeur ne doit pas être supérieure à 1000, sinon un avertissement console est généré et la valeur forcée à 1000. debrisNumVariance Integer 0 Un nombre aléatoire entre -1*debrisNumVariance et debrisNumVariance est généré et ajouté à debrisNum pour déterminer le nombre d'objets Debris que l'explosion créera et éjectera. Cependant, de multiples objets Debris peuvent partager le même datablock ExplosionData, mais avoir des comportements variés. La valeur ne doit pas être supérieure à 1000, sinon un avertissement console est généré et la valeur forcée à 1000. Des valeurs supérieures à debrisNum sont acceptées ; si le nombre total d'objets Debris à générer est négatif, aucun objet Debris ne sera créé. debrisVelocity Float 2.0 Utilisé avec debrisVelocityVariance pour déterminer la vitesse à laquelle les objets Debris seront émis par l'explosion. Une valeur inférieure à 0.1 génère un avertissement console et la valeur est forcée à 0.1. Pour préserver la transmission réseau, la valeur debrisVelocity est multipliée par 10 et stockée sous la forme d'un entier de 14 bits, ainsi la vitesse utilisée est précise à +/- 0.1, de la valeur indiquée, et les valeurs inférieures à 1639 sont impossibles. 213 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description debrisVelocityVariance Float 0.0 Un nombre aléatoire entre -1*debrisVelocityVariance et debrisVelocityVariance est généré et ajouté à debrisVelocity pour déterminer la vitesse à laquelle les objets Debris, que l'explosion créera, seront émis. Une valeur supérieure à 1000 générera un avertissement console et la valeur sera forcée à 1000. debrisVelocityVariance est multipliée par 10 et stockée sous la forme d'un entier de 14 bits comme pour debrisVelocity. shakeCamera Boolean False Indique si l'effet de secousse de caméra sera joué lorsque la caméra est, au plus, à la distance camShakeRadius de l'explosion. camShakeFreq Point3F (10.0, 10.0, 10.0) Fréquence à laquelle la caméra est secouée pour l'axe x, y et z. camShakeAmp Point3F (1.0, 1.0, 1.0) Amplitude avec laquelle la caméra est secouée pour l'axe x, y et z. camShakeDuration Float 1.5 Durée de secousse de la caméra. camShakeRadius Float 10.0 Distance maximale à laquelle peut être la caméra afin d'être secouée par l'explosion. Également utilisé pour limiter l'amplitude de secousse initiale de la caméra ; plus la caméra est proche de la limite de la zone de secousse de caméra de l'explosion, définie par camShakeRadius, et plus faible est l'amplitude de la secousse initiale de la caméra. camShakeFalloff Float 10.0 Facteur de décroissance de secousse de la caméra utilisé pour l'amortissement temporel de l'amplitude de la secousse. shockwaveOnTerrain Boolean False Note : ce champ n'a actuellement aucun effet tangible. L'effet Shockwave n'est actuellement pas implémenté. Comme vous pouvez le voir, ExplosionData est un datablock assez grand et compliqué, mais il fournit un système flexible d'explosion pour Torque qui peut créer certains effets compliqués avec un très bon aspect visuel. Dans la section suivante, nous commencerons l'examen du système de datablock de particules de Torque. Premièrement, nous étudierons ParticleNodeData et ParticleEmitterData. Ces deux datablocks finiront notre étude sur les dérivés de GameBaseData. Ensuite, nous finirons le système de particules en regardant le datablock ParticleData, qui est simplement dérivé de SimBlockData. 214 / 223 Documentation de Torque V1.3.x D.18 ParticleEmitterNodeData et ParticleEmitterData Le système de particules de Torque est très puissant. Il y a trois sortes de datablocks associés avec le système de particules : ParticuleEmitterNodeData, ParticuleEmitterData et ParticuleData. Dans cette section, nous examinerons les datablocks ParticuleEmitterNodeData et ParticuleEmitterData. Nous regarderons séparément ParticuleData dans la prochaine section. ParticuleEmitterNodeData et ParticuleEmitterData sont tous deux dérivés de GameBaseData. En fait, ce sont les seuls dérivés de GameBaseData que nous n'avons pas encore étudiés. Les datablocks ParticuleEmitterData sont utilisés pour les objets ParticleEmitter. Les objets ParticleEmitter sont censés être attachés à d'autres objets tels des joueurs ou des véhicules. Les objets ParticleEmitterNode fournissent une structure,sur laquelle créer des ParticleEmitter autonomes. Ainsi, plutôt que d'être contraint d'utiliser uniquement des ParticleEmitter sur les objets de forme, nous pouvons à la place initialiser un ParticleEmitterNode et avoir un ParticleEmitter n'importe où dans notre monde. Le datablock ParticleEmitterNodeData est simple. Il contient un seul champ, timeMultiple. Champs de ParticleEmitterNodeData : Nom Type Valeur par Description défaut timeMultiple Float 1.0 Utilisé pour paramétrer l'échelle temporelle pour les émissions de particules (voir la documentation ParticleEmitterData pour plus de détails sur le fonctionnement de l'émission de particules). La valeur du champ timeMultiple doit être comprise entre 0.01 et 100.0, sinon un avertissement console sera généré et la valeur forcée de manière appropriée. Après avoir regardé le champ unique ParticleEmitterNodeData, nous sommes prêts à regarder le datablock ParticuleEmitterData. Ce n'est pas le datablock le plus compliqué que nous aurons abordé, mais ses champs peuvent être utilisés pour créer une large gamme impressionnante d'effets de particules dans le TGE. Champs de ParticleEmitterData : Nom Type Valeur par défaut Description particles String NULL Chaîne contenant une liste de noms de datablocks ParticleData séparés par une tabulation. Lorsqu'une particule est émise, son datablock est sélectionné aléatoirement dans la liste des datablocks valides indiqués dans le champ particles. La chaîne ne doit pas être vide et doit contenir au moins un nom valide de datablock ParticleData. La chaîne doit également avoir une longueur inférieure à 256 caractères. Si une de ces conditions n'est pas remplie, un avertissement console sera généré et la méthode onAdd() échouera. ejectionPeriodMS Integer 100 Utilisé avec periodVarianceMS pour déterminer la fréquence d'émission des particules. Voir le champ periodVarianceMS pour plus de détails. Stocké avec seulement 10 bits de précision, ainsi les valeurs supérieures à 1023 ne sont pas possibles. Si la valeur est inférieure à 1, un avertissement console est généré et la valeur forcée à 1. 215 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description periodVarianceMS Integer 0 Utilisé avec ejectionPeriodMS pour déterminer la fréquence d'émission des particules. Chaque fois qu'une particule est émise, une valeur aléatoire comprise entre -1* periodVarianceMS et periodVarianceMS est générée et ajoutée à ejectionPeriodMS pour déterminer le délai d'émission de la prochaine particule. Ainsi, avec les valeurs par défaut ejectionPeriodMS=100 et periodVarianceMS=0, les particules seront émises exactement 10 fois par seconde. La valeur de ce champ est stockée avec seulement 10 bits de précision, ainsi les valeurs supérieures à 1023 ne sont pas possibles. La valeur doit être inférieure à la valeur ejectionPeriodMS, sinon un avertissement console est généré et la valeur forcée à ejectionPeriodMS-1. thetaMin Float 0.0 Chaque fois qu'une particule est émise, on donne une direction d'éjection. Cette direction est définie par les champs thetaMin, thetaMax, phiReferenceVel et phiVariance. Un angle aléatoire compris entre thetaMin et thetaMax est généré et indique l'angle directif d'éjection par rapport à l'axe x. L'angle est en degrés. La valeur doit être comprise entre 0.0 et 180.0, et inférieure à thetaMax sinon, un avertissement console sera généré et la valeur forcée. thetaMax Float 90.0 Chaque fois qu'une particule est émise, on donne une direction d'éjection. Voir thetaMin pour plus de détails. thetaMax définit l'angle directif maximal relatif à l'axe x. L'angle est en degrés. La valeur doit être comprise entre 0.0 et 180.0, sinon un avertissement console sera généré et la valeur forcée. phiReferenceVel Float 0.0 Chaque fois qu'une particule est émise,on donne une direction d'éjection. Voir thetaMin pour plus de détails. phiReferenceVel et phiVariance déterminent l'angle d'éjection des particules suivant l'axe z. Les particules sont émises en commençant à 0.0 degré, et l'angle d'émission augmente avec le temps, suivant la vitesse indiquée dans phiReferenceVel et les nombres aléatoires générés via phiVariance. Voir la documentation de phiVariance. La valeur de ce champ est en degrés par seconde et doit être comprise entre 0.0 à 360.0, sinon un avertissement console sera généré et la valeur forcée. phiVariance Float 360.0 Utilisé avec phiReferenceVel pour déterminer l'angle d'éjection d'une particule relatif à l'axe z. chaque fois qu'une particule est produite, une nouvelle direction d'éjection est déterminée. L'angle d'éjection suivant l'axe z est défini par l'ajout d'une valeur aléatoire comprise entre 0.0 et phiVariance à l'angle déterminé par phiRefVelocity. Voir phiRefVelocity pour plus de détails. La valeur est en degrés et doit être comprise entre 0.0 et 360.0, sinon un avertissement console sera généré et la valeur forcée. ejectionOffset Float 0.0 À chaque particule est donnée une direction d'éjection, et ejectionOffset indique la distance dans cette direction vers laquelle l'émetteur de la particule l'émettra. La valeur de ce champ ne doit pas être négative, sinon un avertissement sera généré et la valeur forcée à 0.0. La valeur ejectionOffset actuelle utilisée est à +/0.01, et les valeurs supérieures à 655 ne sont pas possibles. 216 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description ejectionVelocity Float 2.0 Utilisé avec velocityVariance pour déterminer la vitesse initiale d'éjection d'une particule. Voir la documentation sur velocityVariance pour plus de détails. La valeur de ce champ ne doit pas être négative, sinon un avertissement sera généré et la valeur forcée à 0.0. La valeur ejectionOffset actuelle utilisée est à +/- 0.01, et les valeurs supérieures à 655 ne sont pas valides. velocityVariance Float 1.0 Utilisé avec ejectionVelocity pour déterminer la vitesse d'éjection d'une particule. Chaque particule obtient une nouvelle vitesse, qui est calculée en ajoutant un nombre aléatoire entre -1*velocityVariance et velocityVariance à ejectionVelocity. La valeur de ce champ ne doit pas être négative, ni supérieure à ejectionVelocity, sinon un avertissement sera généré et la valeur forcée limitée. La valeur actuelle utilisée est à +/- 0.01, et les valeurs supérieures à 163 ne sont pas valides. orientParticles Boolean False Indique si les particules émises doivent être orientées comme un panneau d'affichage (toujours directement face à la caméra), ou si elles font face à la direction d'émission (voir la documentation sur thetaMin, thetaMax, phireferenceVel et phiVariance pourplus d'information sur la direction d'émission). True signifie que la particule devra être orientée vers la direction d'émission, false indique les particules devront être orientées face à la caméra. orientOnVelocity Boolean True Applicable uniquement lorsque orientParticles est à true. Indique si les particules émises seront testées pour leur vitesse. Si true, et que la particule n'a pas de vitesse, elle ne sera pas rendue, alors que si elle a une vitesse, celle-ci affectera la taille rendue de la particule. False indique que la vitesse de la particule n'affectera pas la taille rendue. userEmitterSizes Boolean True Indique si le champ du tableau sizes du datablock de la particule devra être surchargé par le tableau sizes fournit par l'objet ParticleEmitter. True implique que le datablock de la particule devra être surchargé. userEmittersColors Boolean True Indique si le champ tableau colors du datablock de la particule devra être surchargé par le tableau colors fourni par l'objet ParticleEmitter. True implique que le datablock de la particule devra être surchargé. overrideAdvance Boolean False Indique si une l'accélération, couleur, ou autres paramètres d'une particule nouvellement créée devra commencer immédiatement à être mis à jour après sa création. Si false, la nouvelle particule est mise à jour immédiatement. Si true, le système d'avancement temporel des particules est reporté. lifetimeMS Integer 1000 Utilisé avec lifetimeVarianceMS pour déterminer la durée de vie totale de chaque particule émise. Valeur en millisecondes. La valeur de ce champ doit être supérieure à 0, sinon un avertissement console est généré et la valeur forcée à 1. Pour préserver la bande passante du réseau, la valeur lifetimeMS est décalée à droite de 5 bits, impliquant une perte de précision. Cependant, la valeur de la durée de vie utilisée peut être inférieure de 31 millisecondes à la valeur indiquée. Après le décalage, la valeur est limitée à 10 bits de précision ; les valeurs supérieures à 32000 millisecondes auront un comportement imprévu. 217 / 223 Documentation de Torque V1.3.x Nom Type lifetimeVarianceMS Integer Valeur par défaut Description 0 Utilisé avec lifetimeMS pour déterminer la durée de vie totale de chaque particule émise. Valeur en millisecondes. Chaque fois qu'une particule est créée, un nombre aléatoire compris entre -1*lifetimeVarianceMS et lifetimeVarianceMS est généré et ajouté à lifetimeMS pour déterminer la durée de vie totale de la particule. La valeur de ce champ ne doit pas être supérieure à lifetimeMS, sinon un avertissement console est généré et la valeur limitée. La valeur lifetimeVarianceMS est décalée et stockée avec une précision de 10 bits de la même manière que la valeur lifetimeMS. Le système de particule de Torque est très robuste, et simple à utiliser. Comme vous pouvez le voir, les datablocks ParticuleEmitterNodeData et ParticuleEmitterData ne sont pas extraordinairement complexes, ils peuvent être utilisés pour produire automatiquement quelques effets géniaux. Il reste encore à étudier un datablock relatif aux particules : ParticleData. ParticleData ne dérive pas de GameBaseData. En effet, nous avons terminé l'examen de tous les datablocks de GameBaseData. Maintenant, avec ParticleData dans la section suivante, nous retournons à l'étude des datablocks dérivant plus fondamentalement de SimData. 218 / 223 Documentation de Torque V1.3.x D.19 ParticleData Nous avons détaillé les champs impliqués dans les datablocks ParticleEmitterData et ParticleEmitterNodeData. Maintenant, nous allons regarder le bloc de donnée ParticleData lui-même. ParticleEmitterData et ParticleEmitterNodeData sont dérivés de GameBaseData, mais pas ParticleData. Lui, il dérive directement du datablock SimDataBlock. Rappelez-vous que SimDataBlock ne définit aucun champ accessible via TorqueScript, alors que ParticleData définit les champs listés ci-dessous : Nom Type Valeur par défaut Description Données de rendu textureName Filename 0 Chemin et nom d'un fichier de texture à utiliser pour la particule. animTextName Filename 0 (array) [PDC_MAX _TEX=50] Chemin et nom de fichiers de texture additionnels à utiliser si le champ animateTexture est à true. animateTexture Boolean False Indique si la texture de la particule est animée. Si true, les trames de texture sont animées à la vitesse indiquée dans le champ framesPerSec. framesPerSec Integer 1 Nombre de trames de texture à afficher par seconde sur la particule. La valeur doit être inférieure à 200, sinon un avertissement console est généré et la valeur est forcée à 20. useInvAlpha Boolean False Indique si le canal alpha dans les trames de texture doit être traité comme s'il était inversé. Il est possible de fournir des textures transparentes ou partiellement transparentes pour les particules ; par défaut, un texel30 alpha avec une valeur de 0.0 implique une transparence totale, alors qu'un texel alpha avec une valeur de 1.0 implique une opacité complète. Si useInvAlpha est true, la situation est inversée, avec un texel alpha à 0.0 représentant l'opacité complète et 1.0 représentant la transparence totale. colors ColorF (array) (1.0, 1.0, 1.0, 1.0) [PC_COLO R_KEYS] Liste des couleurs à utiliser pour la particule à chaque valeur temporelle spécifiée dans le tableau du champ times. La première entrée dans le tableau colors correspond à la couleur initiale de la particule, et est interpolée avec colors[1] jusqu'à ce que times[0] % de la durée de vie soit écoulé, moment auquel la couleur colors[1] est utilisée et débute l'interpolation avec colors[2]. Voir la documentation des champs times, lifetimeMS et lifetimeVarianceMS pour plus d'information. sizes Float (array) 1.0 [PC_SIZE_ KEYS] Liste des tailles à utiliser pour la particule à chaque valeur temporelle spécifiée dans le tableau du champ times. La première entrée dans le tableau sizes correspond à la taille initiale de la particule, et est interpolée avec sizes[1] jusqu'à ce que times[0] % de la durée de vie soit écoulé, moment auquel la couleur sizes[1] est utilisée et débute l'interpolation avec sizes[2]. Voir la documentation des champs times, lifetimeMS et lifetimeVarianceMS pour plus d'information. 30 En infographie, le texel est le plus petit élément d'une texture appliquée à une surface. C'est un pixel texturé. 219 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description times Float (array) [0.0, 1.0, 2.0, 2.0] Chaque entrée est une valeur comprise 0.0 et 1.0 représentant un pourcentage de la durée de vie de la particule. Ces pourcentages temporels sont utilisés tout au long de la durée de vie de la particule afin de déterminer sa couleur et sa taille de tracé. Voir la documentation des champs colors et sizes pour plus d'information. Les entrées doivent être données dans l'ordre ascendant, si une entrée est inférieure à une entrée précédente, elle sera ignorée. Les entrées doivent aussi être comprises entre 0.0 et 1.0. Si une entrée ne l'est pas, elle est ignorée, ainsi que toutes les entrées suivantes. Données physiques dragCoefficient Float 0.0 Représente la propriété physique de la vitesse de déplacement générale dans la simulation physique de la particule. Utiliser pour amortir la vitesse d'une particule, dragCoefficient est multiplié par la vitesse courante et le résultat est soustrait de la vitesse courante.. Cette valeur ne doit pas être négative, sinon un avertissement console est généré et la valeur forcée à 0.0. La valeur actuelle utilisée est seulement garantie à +/-0.2 de la valeur indiquée, et celles supérieures à 204.6 peuvent se comporter incorrectement. windCoefficient Float 1.0 Le moteur peut indiquer un vecteur vitesse de vent, et le vecteur peut être appliqué afin que l'effet de la vitesse du vent simulé affecte en conséquence l'accélération d'une particule (la vitesse globale du vent est multipliée par windCoefficient et le résultat soustrait de l'accélération de la particule). gravityCoefficient Float 0.0 Multiple scalaire appliqué à la force de gravité avant qu'elle n'affecte l'accélération de la particule. La valeur actuelle utilisée n'est garantie qu'à +/-0.1 de la valeur indiquée. inheritedVelFactor Float 0.0 Multiple scalaire appliqué à vitesse donnée à la particule lors de sa création. Voir la documentation du champ ejectionVelocity pour plus d'information. constantAcceleration Float 0.0 Représente l'accélération constante de base des particules. Lors de la création, la particule est transmise avec cette accélération. Durant la simulation physique, la particule continue d'accéler avec ce taux constant, cependant elle peut être aussi affectée par le déplacement, le vent et la gravité (voir la documentation des champs dragCoefficient, windCoefficient et gravityCoefficient pour plus d'information). spinSpeed 0.0 Utilisé avec spinRandomMin et spinRandomMax pour déterminer la vitesse de rotation des particules (voir les champs spinRandomMin et spinRandomMax pour plus d'information). La valeur de ce champ doit être comprise entre -10000.0 et 10000.0, sinon un avertissement console sera généré. Float 220 / 223 Documentation de Torque V1.3.x Nom Type Valeur par défaut Description spinRandomMin Float 0.0 Utilisé avec spinSpeed et spinRandomMax pour déterminer la vitesse de rotation des particules (voir le champ spinRandomMax pour plus d'information). La valeur de ce champ doit être comprise entre -10000.0 et 10000.0, sinon un avertissement console sera généré et la valeur forcée à -360.0. La valeur ne doit pas être supérieure à spinRandomMax, sinon elle sera inversée (si spinRandomMin = spinRandomMax + 100, alors spinRandomMin sera ajusté à spinRandomMax – 100). spinRandomMax Float 0.0 Utilisé avec spinSpeed et spinRandomMin pour déterminer la vitesse de rotation des particules. Un nombre aléatoire compris entre spinRandomMin et spinRandomMax est généré et le résultat est ajouté à la valeur indiquée dans le champ spinSpeed pour déterminer une vitesse de rotation actuelle de particule. La valeur doit être compris entre -10000.0 et 10000.0, sinon un avertissement console sera généré et la valeur forcée à 360.0. La valeur doit aussi ne pas être supérieure à spinRandomMax, sinon elle sera inversée (si spinRandomMin = spinRandomMax + 100, alors spinRandomMin sera ajusté à spinRandomMax – 100). Données comportementales lifetimeMS Integer 1000 Utilisé avec lifetimeVarianceMS pour déterminer la durée de vie totale de chaque particule émise. Valeur en millisecondes. La valeur doit être supérieure à 0, sinon un avertissement console est généré et la valeur forcée à 1. Pour préserver la bande passante du réseau, la valeur de lifetimeMS est décalée de 5 bits à bits, impliquant une perte de précision. Cependant, la durée de vie utilisée peut être inférieure de 31 millisecondes que la valeur indiquée. Après le décalage, la valeur est limitée à 10 bits de précision ; cependant, les valeurs de plus de 32000 millisecondes pourront impliquer un comportement imprévu. lifetimeVarianceMS Integer 0 Utilisé avec lifetimeVarianceMS pour déterminer la durée de vie totale de chaque particule émise. Valeur en millisecondes. Chaque fois qu'une particule est créée, un nombre aléatoire compris entre (-1* lifetimeVarianceMS) et lifetimeVarianceMS est généré et ajouté à lifetimeMS pour déterminer la durée de vie totale de la particule. La valeur ne doit pas être supérieure à lifetimeMS, sinon un avertissement console sera généré et la valeur forcée à (lifetimeMS-1). La valeur lifetimeVarianceMS est décalée et stockée avec 10 bits de précision de la même manière que pour le champ lifetimeMS. Avec ceci, nous avons une référence de tous les datablocks du moteur de particules de Torque. Dans la prochaine section, nous poursuivrons l'étude des dérivés du datablock SimDataBlock. En fait, nous jetterons un coup d'œil aux datablocks WheeledVehicle et WheeledVehicleSpring qui ont déjà été mentionnés. 221 / 223 Documentation de Torque V1.3.x D.20 WheeledVehicleTire et WheeledVehicleSpring Nous continuons notre étude des datablocks dérivés directement de SimDataBlock par l'examen des derniers datablocks relatifs aux véhicules du TGE, WheelVehicleTire et WheeledVehicleSpring. Bien que ces datablocks soient utilisés dans le système de véhicule de Torque, les datablocks eux-mêmes sont assez simples et ne nécessitent pas de dériver de ShapeBaseData, ou même de GameBaseData. Nous étudierons en premier le datablock WheeledVehicleTire. Comme son nom l'implique, ce datablock est destiné à encapsuler les données correspondant aux véhicules à pneus. Dans la physique des véhicules à roues, les pneus jouent un rôle important et Torque cherche à modéliser leur rôle dans le comportement du véhicule autant que possible en temps réel. La table suivante donne une description détaillée de chacun des champs du datablock WheeledVehicleTire. Nom Type Valeur par Description défaut shapeFile Filename radius Float mass Float staticFriction Float 1.0 Utilisé dans la simulation physique pour représenter le frottement du pneu lorsqu'il ne glisse pas (avec traction). kineticFriction Float 0.5 Utilisé dans la simulation physique pour représenter le frottement du pneu lorsqu'il glisse (sans traction). lateralForce Float 10.0 Utilisé dans la simulation physique pour représenter la force latérale du pneu. La force latérale peut être simplement considérée comme une force directionnelle gauche/droite. Les véhicules à roues sont sensibles aux forces générées par leurs pneus et la force latérale mesure l'amplitude de la force exercée sur le véhicule lorsque les pneus sont déformés suivant l'axe x. Avec les véhicules réels à roues, les pneus constamment déformés et c'est l'effet des forces de déformation qui détermine comment un véhicule se déplace. Dans les simulations Torque des véhicules physiques, la déformation des pneus ne peut évidemment pas être gérée avec un réalisme absolu, mais la vélocité du véhicule, le couple moteur et les forces de freinage, le frottement des roues, la déformation latérale et longitudinale, associés avec la vitesse angulaire des roues sont combinés pour créer une simulation physique en temps réel robuste. Pour ce champ, plus la valeur fournie pour la force latérale est grande, plus l'effet de mouvement de direction sera important. Dans Torque, les forces des pneus sont appliquées au niveau du moyeu des roues du véhicule. lateralDamping Float 1.0 Indique la force d'amortissement appliquée contre les forces latérales générées par les pneus. Voir le champ lateralForce pour plus d'information. Chemin et nom d'un fichier de forme à utiliser pour la roue. 0.6 Rayon du pneu. Le rayon est déterminé à partir de la boîte d'encadrement de la forme fournie dans le champ shapefile, et ne nécessite pas d'être indiqué dans un script. Le pneu doit être construit avec son pivot suivant l'axe y de l'objet. Masse de la roue entière. Utilisé dans la simulation physique, voir la documentation du datablock WheeledVehicleData pour plus d'information. La masse de la roue ne nécessite pas d'être indiquée dans un script. 222 / 223 Documentation de Torque V1.3.x Nom Type Valeur par Description défaut lateralRelaxation Float 1.0 Indique la force de détente appliquée contre les forces latérales générées pas les pneus. La force lateralRelaxation indique la force effective de non-déformation des pneus. Voir le champ lateralForce pour plus d'information. longitudinalForce Float 10.0 Utilisé dans la simulation physique pour représenter la force longitudinale des pneus. La force longitudinale peut simplement être considérée comme une force de mouvement avant/arrière. Les véhicules à pneus font l'objet de forces générées par leurs pneus et longitudinalForce indique l'amplitude de la force exercée sur le véhicule lorsque les pneus sont déformés suivant l'axe y. Voir le champ lateralForce pour plus d'information. Pour ce champ, plus la valeur fournie pour la force longitudinale est grande, plus l'effet d'accélération/décélération sera important. longitudinalDamping Float 1.0 Indique la force d'amortissement appliquée contre les forces longitudinales générées par les pneus. Voir les champs longitudinalForce et laterForce pour plus d'information. longitudinalRelaxation Float 1.0 Indique la force de détente appliquée contre les forces longitudinales générées par les pneus. La force longitudinalRelaxation indique la force effective de nondéformation des pneus. Voir le champ longitudinalForce et laterForce pour plus d'information. restitution 1.0 Note : actuellement, ce champ n'a aucun d'effet tangible dans la simulation du moteur. Float Depuis que nous avons maintenant référencé le datablock WheeledVehicleTire, le dernier datablock à étudier est WheeledVehicleSpring. Il simule l'effet du système de suspension d'un véhicule. Nom Type Valeur par Description défaut force Float 10.0 Force de la suspension. Les forces de suspension agissent directement vers le haut et sont appliquées à la base du ressort, défini dans la forme du véhicule. lenght Float 1.0 Longueur du ressort de suspension à partir de la base. damping Float 1.0 Force d'amortissement contrecarrant la force du ressort. antiSwayForce Float 1.0 Force chargée d'amortir le balancement latéral introduit lorsque des roues opposées sont à des hauteurs différentes. La physique des véhicules à roues, leurs pneus et les systèmes de suspension peuvent être difficiles à comprendre. Ne soyez pas intimidé si la manière nuancée, avec laquelle tous les champs que nous avons examinés interagissent avec les autres, ne prend pas immédiatement de sens. Les descriptions offertes dans mes tableaux précédents et dans la documentation du datablock WheeledVehicleData décrivent à un niveau relativement élevé comment la physique des véhicules à roues est simulée dans Torque, et à quoi servent les champs des datablocks relatifs aux véhicules. Mais ne comptez pas devenir un maître du système complexe de la physique des véhicules à roues dans Torque, après avoir simplement lu les références de ce datablock. 223 / 223