Je vais vous parler ici de l'optimisation des scripts. Tout d'abord, pourquoi faire ? Est-ce bien utile ?
Et bien, le gain de performance sera mineur en cours du jeu, les problèmes de fluidité venant principalement de la carte graphique, par contre, cela permet d'éviter de trop ralentir les phases de chargement quand on change de cellules, en particulier avec les blocs OnLoad.
Puis, je ne dois pas être la seule maniaque du forum...
(ceci est une synthèse de ce que j'ai pu trouver dans les doc anglaises)
(certaines de ces astuces peuvent être utiles pour morrowind (surtout, car il dépend bien plus du processeur qu'oblivion) et fallout)
(c'est une ébauche, donc toute aide est la bienvenue)
Les tests et les opérateurs.
Voici un script du jeu de base:
if timer <= 0 && getstage MQ15 == 58 && OrtheRef.getdead == 0 set timer to 5 sayTo player MQ15EldamilWarning endif if timer <= 0 && getstage MQ15 == 66 && getdistance player < 1000 if suicide == 0 set timer to sayTo player MQ15EldamilWarning set suicide to 1 endif endif if suicide == 1 && getstage MQ15 == 66 && timer <= 0 setstage MQ15 67 endif
Nous pouvons voir qu'il y a trois tests if et que pour chacun de ceux-ci a deux opérateurs logiques &&.
Il faut savoir qu'en l'état, le jeu va tester les trois if, et que pour chaque if, il va tester les trois conditions à chaque fois, même si la première du if est fausse, donc au total, par frame, le jeu va tester neuf conditions.
Or, en disposant les if en cascade, si la première condition est fausse, le jeu ne testera pas les autres conditions qui suivent.
En disposant le script comme ceci:
if timer <= 0 if getstage MQ15 == 58 if OrtheRef.getdead == 0 set timer to 5 sayTo player MQ15EldamilWarning endif elseif getstage MQ15 == 66 if getdistance player < 1000 if suicide == 0 set timer to sayTo player MQ15EldamilWarning set suicide to 1 elseif suicide == 1 setstage MQ15 67 endif endif endif endifLe jeu, ne fera tout d'abord que le test if timer <= 0,si ce dernier est vrai, il va continuer, mais si il est faux, il n'ira pas plus loin, dans cette dernière situation, on économisera 8 tests par frame.
Toutefois, dans le cas où la première condition est souvent vérifiée, l'exécution n'en sera que plus lente si on split en deux tests. Il faut donc placer en premier les variables les moins souvent vraies.
Et bien entendu cette astuce n'est réellement utile que dans les blocs GameMode.
Concernant les opérateurs de comparaison (==, !=, <=...).
Moins le jeu en a, mieux il se porte en terme de réactivité, concrètement, comment utiliser ce fait ?
Lorsqu'une variable est de type booléenne, c'est à dire qu'elle n'a que deux états logiques, dont l'un est 0.
En effet, écrire:
if GetDead
Revient à écrire:
if GetDead != 0
Donc si GetDead prend la valeur de 1 ou encore, soyons fou, 63 ou 0.5, le test sera considéré comme vrai, et si elle a pour valeur 0, le test sera considéré comme faux.
Il en va de même, préférez les tests de type else quand c'est possible, puisqu'il n'y a pas d'opérateur possible avec ce dernier.
Petit exemple à partir d'un script commun dans ce jeu:
;script normal if next == 1 && timer <=0 set next to 0 myParent.activate mySelf 1 endif if timer > 0 set timer to timer - getSecondsPassed endif ;script optimisé if timer > 0 set timer to timer - getSecondsPassed else ;>0 étant le complément de <=0, un else fait parfaitement l'affaire if next ;disparition de l'opérateur == set next to 0 myParent.activate mySelf 1 endif endif
Les Return.
Cette astuce nous vient directement de morrowind, et elle fonctionne sur oblivion (et fallout je suppose du coup...).
Quand on a des résultats très lourds, il peut être avantageux d'utiliser la fonction return, en effet, même si le test if est faux, le jeu peut lire son résultat, ce qui alourdit inutilement le temps processeur...
Petit exemple:
; non-optimisé begin GameMode if test (un résultat très très lourd) endif end ; optimisé begin GameMode if test == 0; négation du test précédent RETURN endif (un résultat très très lourd) endDans la seconde situation, le moteur de script lisant les scripts de haut en bas, si le test == 0 est vrai, il va tomber sur un return qui lui dit de recommencer la lecture du script depuis le début, et donc tout ce qui est après n'est pas lu.
Il faut donc utiliser ceci en tout fin de script forcément, à moins qu'il ne soit construit de manière ordonnée.
Ce qui est gourmant en temps processeur:
La première chose qu'il faut faire, c'est éviter au maximum l'utilisation des blocs GameMode, car ceux-ci sont exécutés à chaque frame, cependant que les blocs OnLoad, eux, ne fonctionnent que pendant la période de chargement et donc influent sur celle-ci.
Voir la liste des blocs disponibles.
Même si oblivion dépend beaucoup moins du processeur que morrowind, certaines choses sont à éviter au possible pour éviter que le processeur ne souffre de trop.
Tout d'abord, quatre fonctions de scripts ont été classées comme étant très gourmandes:
GetNumItems (OBSE)
GetInventoryObject (OBSE)
GetFPS (OBSE)
GetDistance
Ces fonctions posent problèmes principalement si elles sont exécutées souvent, par exemple dans un bloc GameMode.
Evitez autant que possible les Low level Processing en cochant la case No Low Level Processing pour les acteurs.
Low level Processing indique que l'IA de l'acteur fonctionnera même si il n'est pas à proximité du joueur, tandis qu'avec No Low Level Processing, l'IA ne fonctionnera qu'a proximité du joueur, ce qui soulagera le processeur.
Toujours avec l'IA, celle-ci peut être "saturée" si il y a trop de "script IA avancés" autour du joueur, ce qui peut faire buguer des acteurs.