Aller au contenu


Script Pour Labyrinthe.


  • Veuillez vous connecter pour répondre
4 réponses à ce sujet

#1 Vasumitra

Vasumitra

Posté 23 septembre 2012 - 09:00

bonjour tout le monde.

je souhaiterait créer un labyrinthe dans oblivion, MAIS que celui-ci change à chaque fois que l'on y rentre.

Je sais générer des labrynthe, dans le sens ou je sais faire des algos pour en créer (en java par exemple).

Maintenant, j'ignore les possibilités des scripts dans oblivion.

Est-il possible de créer une cellule "à la volée", c'est à dire de la créer via un script ?
Je pense qu'en préparant une cellule vide, puis en la peuplant, ça doit être faisable. Sauf que je ne connais pas vraiment les fonctions pour placer des items à tel endroit (pas par rapport au joueur).

Ensuite, est-ce qu'il existe des tableaux dans les scripts d'oblivion ? Je suis en train de modifier mon script java pour n'utiliser que des tableaux d'entiers, afin que cela soit simple à transcrire dans oblivion.

Est-ce qu'il existe aussi des structures comme des piles (où on peut empiler et dépiler) ?

mon script java est parfaitement fonctionnel, c'est juste que je ne suis pas familier avec les scripts d'oblivion (j'ai un peu bossé sur ceux de morrowind par contre).

#2 Shadow she-wolf

Shadow she-wolf

    Le katana de la GBT


Posté 23 septembre 2012 - 09:09

Coucou...

C'est possible dans Morrowind...
Donc ça doit être possible dans Oblivion...

Il est à noter que c'est fait sans script extender... Et selon le lisez-moi ce site contient tous les algo nécessaires...

Voir le messageVasumitra, le 23 septembre 2012 - 09:00, dit :

Ensuite, est-ce qu'il existe des tableaux dans les scripts d'oblivion ? Je suis en train de modifier mon script java pour n'utiliser que des tableaux d'entiers, afin que cela soit simple à transcrire dans oblivion.

Est-ce qu'il existe aussi des structures comme des piles (où on peut empiler et dépiler) ?
Pas sans OBSE...

#3 Kafou

Kafou

    Le canari a bouffé le rominet !


Posté 23 septembre 2012 - 10:53

Salut, je suis l'auteur du mod cité par  SSW. Je t'invite à le télécharger et te pencher sur mes scripts pour voir ce que donnent en pratique les instructions que je vais te donner ici.

Il y a de nombreux problèmes à prendre en compte pour ce type de script, mais rien d'insurmontable.

Aucune structure de données dynamique n'est disponible nativement dans Morrowind ou dans Oblivion , il faut donc improviser. Morrowind ne dispose même pas d'un système de références/pointeurs. Celui d'Oblivion n'est pas utilisable dans notre cas (enfin je crois... je sais que le wiwilandais Baka avait expérimenté sur des listes chaînées). Côté Skyrim, pour le peu que je me suis renseigné, les choses ont l'air beaucoup plus simples.

En gros, la solution est matérialiser chaque case du labyrinthe par un objet 3D présent physiquement (mais sans géométrie pour éviter de perdre trop de performances) dans la cellule courante. Le labyrinthe devient alors une grille d'objets qu'on peut adresser via leurs coordonnées X et Y dans la cellule (il suffit de séparer les cases voisines d'une unité).

Ton script principal déroule l'algo et à chaque frame de rendu (c'est-à-dire chaque exécution de l'ensemble des scripts dans Morrowind et Oblivion, c'est différent pour Skyrim) il interroge une ou plusieurs cases en mettant des variables globales aux coordonnées X et Y voulues et une autre à un code identifiant la fonction qu'on souhaite effectuer. Chaque case a un script, qui est une machine à états et qui répond à une question / exécute une fonction si ses coordonnées rentrent dans l'intervalle demandé (souvent l'intervalle ne contient qu'une case). La case se comporte différemment selon les ouvertures qui sont déjà faites et selon sa rotation, tu peux également stocker des variables dedans, par exemple dans mon algo j'utilise un système de groupes pour assurer que le labyrinthe est parfait. On se retrouve alors à vaguement émuler un cas de programmation orientée objet, avec un script principal qui appelle des fonctions diverses sur des objets contenus dans un tableau 2D. On est juste limité à un appel de fonction par frame, et l'adressage et le passage de paramètre sont laborieux, mais ça marche.

En pratique, j'ai choisi d'utiliser plusieurs types de cases pour représenter les différentes combinaisons d'ouvertures, comme c'est fait dans les sets d'architecture (endcap, corner, hall, 3way, 4way, plus un "closed" virtuel qui correspond à une case entièrement fermée), ce qui permet de simplifier les scripts. Quand une case change d'état, elle crée une case du nouveau type au même endroit et à la rotation voulue et se supprime. Heureusement la position et la rotation peuvent être passées directement lors de la création de la nouvelle case, mais ce n'est pas le cas des autres variables qu'il faut alors récupérer en passant par des variables globales (dans Morrowind du moins, quand un objet est créé, il se met à la fin de la liste des objets de la cellule courante, et donc son script s'exécutera forcément dans la même frame que sa création). Enfin, quand une case passe à son état final (on ne l'ouvrera pas plus), elle crée la "vraie" case du labyrinthe (avec géométrie et en ajustant la position) dans une autre cellule.

Le dernier problème c'est les performances. Vu qu'on est limité par le nombre de frames par seconde, il faut éviter de perdre trop de FPS, et éviter d'avoir besoin de trop de frames. Là c'est tout un travail d'optimisation et il faut très bien connaître le système de script pour pouvoir arriver à des générations de labyrinthes qui ne prennent pas des dizaines de minutes.

Pour Morrowind j'étais arrivé à choisir un algo qui ne nécessite au maximum que deux "lignes" du labyrinthe en mémoire (donc moins de scripts qui tournent à la fois) et qui, par un bienheureux hasard, s'avère aussi très rapide dans son exécution. Sur le lien donné par SSW, il s'agit de l'algorithme d'Eller. J'ai aussi (et surtout) fait en sorte (à coups de mises à jour sur plusieurs années) de factoriser au maximum les opérations effectuées sur les cases pour au final réduire par 2 le nombre de frames nécessaires par case comparé à l'implémentation naïve. Malheureusement pour cette raison l'algo peut sembler très obscur dans Laby Connection.

Par contre je ne connais pas le système de scripts d'Oblivion... mais je sais que le wiwilandais Ced (qui doit encore passer de temps en temps comme moi) s'était penché sur la question. Il avait d'ailleurs, il me semble, réussi à faire de la génération de labyrinthe dans Oblivion, mais s'était heurté à des problèmes que je n'avais pas dans Morrowind. Notamment, dans Oblivion il est impossible de supprimer définitivement un objet, ce qui est très gênant étant donné que pour le labyrinthe on doit utiliser des objets temporaires, et surtout quand on a fini le labyrinthe on souhaite le supprimer pour pouvoir en générer un nouveau ensuite. On dirait bien qu'OBSE est nécessaire pour obtenir quelque chose d'équivalent à Laby Connection.

En tout cas, bon courage ! Et n'hésite pas à me contacter si tu veux plus d'infos.
You look like you need a monkey!

Attention : perfectionniste paresseux.

#4 Vasumitra

Vasumitra

Posté 23 septembre 2012 - 11:26

merci pour ces réponses. Je vais me pencher sur tout ça.

Sinon, j'ai repensé à cette salle dans oblivion où les murs se lèvent pour nous enfermer alors que le gaz envahit la pièce.

En préparant une cellule pleine de "salle" comme ça (avec tous les murs levés) on perdrait le coté "taille dynamique", mais on gagnerait en simplicité: il suffirait de faire qu'à chaque frame chaque cellule pouvant ouvrir une de ses voisines (là je m'interroge sur comment faire sans créer 10.000 copié collé de scripts) tire un numéro au hasard, et seul le numéro le plus élevé s'ouvrirait, afin d'éviter que deux pièce décident d'ouvrir une voisine en même temps.

Il est vrai que sans structure dynamique, cela a l'air difficile. Je suis aussi tombé sur des trucs qui parle de obse (une extension des scripts à priori) et ça a l'air plus faisable ici.

l'algo que j'utilise (en java) ressemble à:
initialiser avec une seed (une pièce au hasard).
tant qu'il reste des pièces à visiter, en prendre une au hasard.
pour cette pièce, si elle a une voisine qui peut être ouverte, l'ouvrir. Sinon, retirer la pièce que l'on a prise.

De cette façon, je suis sur que toutes les pièces sont ouverte (le test "peut être ouverte" signifie "n'a jamais été ouverte").

Je me pose en revanche des questions sur les performances qui m'amènent à me demander si je ne devrais pas créer des pièces séparées par de vraies portes (avec temps de chargement donc). Ceci dit, ça ne change rien au problème.

Une autre piste qui m'est venue à l'esprit est : est-ce qu'il est possible de lire dans un fichier et d'exécuter un truc externe ? Si les deux sont faisable, alors je peux complètement déléguer tout le problème à un élément externe.

Enfin, merci pour le coup de main, je vais voir ton script ce soir (là je vais dodo je n'ai pas dormi de la nuit).

#5 Kafou

Kafou

    Le canari a bouffé le rominet !


Posté 23 septembre 2012 - 12:03

Voir le messageVasumitra, le 23 septembre 2012 - 11:26, dit :

En préparant une cellule pleine de "salle" comme ça (avec tous les murs levés) on perdrait le coté "taille dynamique", mais on gagnerait en simplicité: il suffirait de faire qu'à chaque frame chaque cellule pouvant ouvrir une de ses voisines (là je m'interroge sur comment faire sans créer 10.000 copié collé de scripts) tire un numéro au hasard, et seul le numéro le plus élevé s'ouvrirait, afin d'éviter que deux pièce décident d'ouvrir une voisine en même temps.
Ca m'a l'air tout à fait possible et intéressant, bien qu'on perde en effet la taille dynamique. Je t'encourage à aller dans cette direction, ça semble plus adapté à Oblivion (sans OBSE).

Pas la peine de copier-coller 10000 fois le même script, tu peux utiliser 10000 cases/portes toutes avec le même script. En pratique le jeu créera autant d'instances de script que nécessaire (chacune avec ses propres valeurs pour les variables), mais ce n'est pas à toi de le faire.

Ton algo a l'air de ressembler à celui de Prim. Je suppose que tu n'as pas tout décrit, parce que tel que tu le dis, il ne crée pas de labyrinthe parfait, et c'est ballot (quand ton labyrinthe n'est pas parfait, tu n'as aucune certitude que l'entrée et la sortie puissent se rejoindre).

Citation

Je me pose en revanche des questions sur les performances qui m'amènent à me demander si je ne devrais pas créer des pièces séparées par de vraies portes (avec temps de chargement donc). Ceci dit, ça ne change rien au problème.
Ca c'est pas gérable, sauf si tu veux t'amuser à créer manuellement autant de cellules qu'il y a de cases dans ton labyrinthe. Et ça risque d'être galère pour synchroniser les scripts tout en détruisant les perfs du jeu.

Citation

Une autre piste qui m'est venue à l'esprit est : est-ce qu'il est possible de lire dans un fichier et d'exécuter un truc externe ? Si les deux sont faisable, alors je peux complètement déléguer tout le problème à un élément externe.
Non c'est pas possible. Pour des raisons évidentes de sécurité.
You look like you need a monkey!

Attention : perfectionniste paresseux.




0 utilisateur(s) li(sen)t ce sujet

0 membre(s), 0 invité(s), 0 utilisateur(s) anonyme(s)