JeuxOnLineForumsPlusConnectés : 186 (sites) | 316 (forums)Créer un compte
Forum jeux-vidéo>Neverwinter Nights
Maskado
Les forums JOL > Forum jeux-vidéo > Neverwinter Nights > NWN - Maskado > [Script] Emulation de l'évènement OnHeartBeat avec moins de charge CPU RSS
   
Fil fermé
Partager Outils Rechercher
Avatar de Jedaï
Jedaï
Alpha & Oméga
 
Avatar de Jedaï
 
Citation:
Bah lol, déjà le delaycommand n'étant pas une action tu fait faire le spawn du monstre par qui par quoi?
Je trouve que cette phrase est étrange de la part de quelqu'un qui se prétend un scripteur fou...
La catégorie "action" dont Bioware nous a gratifié est une généreuse approximation puisque toute fonction qui ne renvoie pas de valeur renvoie visiblement en NWScript un pointeur sur elle-même, seul moyen de passer une fonction en paramètre en C (en C++ en fait).
Or DelayCommand() est une fonction qui renvoie "void", elle est donc tout à fait utilisable en tant qu'action, ce qui fait qu'on peut faire effectuer le Respawn par le module via AssignCommand().
Ignorais-tu cela, toi qui prétend avoir utilisé un système à base de DelayCommand() auparavant (sinon comment as-tu fait tes tests) ?

Par ailleurs tu parle de respawn sur 150 zones, or que je sache tu n'as pas 150 joueurs sur ton module ? Donc respawner sur 150 zones est inutile, tu ferais peut-être bien de considérer les avantages du DelayCommand() sur ce plan.

PS : Par ailleurs, le code source de NWN n'est accessible qu'aux développeurs de Bioware, si tu as des lumières à nous donner sur la façon dont Bioware a programmé son gestionnaire d'évènement, tu peux y aller, ça nous intéresserait énormément. Nous expliquer que le DelayCommand() fonctionne de la même façon que le OnHeartBeat n'est pas significatif si tu ne nous dit pas comment ce dernier fonctionne.
Lien direct vers le message - Vieux
Avatar de Hidwulf
Hidwulf
Roi
 
Avatar de Hidwulf
 
Oula tu n'as pas bien compris justement : AssignCommand()
On est obligé de passer par là c'est bien là le hic... Car dans la mesure du possible il faudrait que l'objet auquel tu assignes la commande n'est pas "trop" d'action a faire dans le temps sinon ...

Je ne parlais pas d'action de personnage mais d'action réelle telle qu'un appel à une fonction. Car de ce fait tu fais un assign command qui va empiler ses action sur le respawnmaster (objet a qui tu alloues tes action de respawn).
De plus, plus tu alloueras d'action a un obje quelqu'il soit plus il aura du mal, car il devrai decompter pour chaque evènement si oui ou non il peut le dépiler. Car là dessus le système est mal concu car il est des plus probable que le assigncommand va fontionner telle une pile et faire du FILO, premier entre, dernier sorti. Et une pile est une pile et comme la gestion des mallocs ne peut être accessible il est fort probable qu'il existe une sorte de tampon qui soit géré par le mod en attendant de pouvoir les transmettre à l'objet qui n'a plus de "place dans la liste de ses actions".

tu veux mon ancien script de respawn avec des delaycommand? soit ... 2s j'ouvre le mod j'en ai pour 5-10 minutes
Lien direct vers le message - Vieux
Avatar de Hidwulf
Hidwulf
Roi
 
Avatar de Hidwulf
 
Code PHP:


void StaticSpawn
(string szClasslocation lWherestring info);

void main()
{

    
XP_RewardXPForKill(); /* gestion xp et fp */ 
    
    
object oSpawnMaster;
    
    
string szMonsterTag GetTag(OBJECT_SELF);
    
int nLength 0;
    
string szSpawnPointTag "";
    
string szSpawnPointInfo;
    
string szMonsterClass;
    
object oSpawnPoint;
    
float fSpawnTime;
    
location lSpawnPoint;
    
    if( 
GetSubString(szMonsterTag03) == "ms_" ) {
    
nLength GetStringLength(szMonsterTag);
    
    
szSpawnPointTag GetSubString(szMonsterTag3, (nLength 3));
    } else {
    
    
szSpawnPointTag GetLocalString(OBJECT_SELF"ms_info");
    }
    
    if(
szSpawnPointTag != "") {
    
    
oSpawnPoint GetWaypointByTag(szSpawnPointTag);
    
szSpawnPointInfo GetName(oSpawnPoint);
    
    
nLength GetStringLength(szSpawnPointInfo);
    
    
fSpawnTime StringToFloatGetSubString(szSpawnPointInfo03) + ".0" );
    
    
szMonsterClass GetSubString(szSpawnPointInfo4, (nLength 4));
    
    
lSpawnPoint GetLocation(oSpawnPoint);
    
    
oSpawnMaster GetObjectByTag("spawnmaster");
    
    
AssignCommand(
    
oSpawnMaster,
    
DelayCommand(fSpawnTimeStaticSpawn(szMonsterClasslSpawnPointszSpawnPointTag))
    );
    }
}

void StaticSpawn(string szClasslocation lWherestring info) {
object oNewMonster CreateObject(OBJECT_TYPE_CREATUREszClasslWhere);
SetLocalString(oNewMonster"ms_info"info);

Bon désolé pour l'indentation mais j'ai pas retrouve une bonne version ca fait un bail que je ne l'utilise plus ...
Lien direct vers le message - Vieux
Avatar de Jedaï
Jedaï
Alpha & Oméga
 
Avatar de Jedaï
 
Hummm, avec un tel script c'est sûr que ça risque de bloquer pas mal : relis les post sur la copie des variables au-dessus.

Par ailleurs c'est étrange que tu dises que les Actions seraient posés dans une structure FILO, ne serait-il pas plus logique que la structure soit de type FIFO ?

Autre chose, il me semble que ton script pourrait, même en dehors du DelayCommand() être optimisé, exemple le stockage du SpawnPoint par une local string au lieu d'un local object : un pointeur prend moins de place qu'une string en mémoire. D'autant plus que GetObjectByTag() est une fonction lourde.

Mais effectivement, tout dépend de ses besoins en Respawn, j'imagine que s'ils sont vraiment massifs, le recours à un OnHeartBeat est moins coûteux.
En effet, tu emploies ici un seul "respawnmaster" pour tout ton module, il est fort probable qu'il soit vite saturé, surtout si tu gères un module où les combats sont nombreux. Tu pourrais, par exemple utiliser GetArea() à la place.
Ce genre de chose peut rendre le script beaucoup plus efficient au final, non ?
Lien direct vers le message - Vieux
Avatar de Hidwulf
Hidwulf
Roi
 
Avatar de Hidwulf
 
Alors ouep je me suis trompe c'est bien du FIFO ...
Ce qui induit que cela bloque les respawn suivant dans la file si le précédent n'est pas fini. Donc en plus si ils n'ont pas la même durée de spawn ..

Et non le fait est que le spawnmaster est unique par zone ou groupe de zone car dans une autre version que je n'ai plus ce n'est pas getobjectbytag mais nearest ce qui allège grandement les scripts.

Le fait d'allouer plustot une chaine des caractère qu'un objet de type waypoint si j'ai bien compris est tout de même assez ennuyeux car coutant en mémoire. Certes l'accès sera des plus rapide mais ademettons une centaine de monstres, 100 pointeurs dessus et je ne suis pas certain que cela soit mieux. Ne pas oublié qu'une chaine de caractère est ni plus ni moins qu'un pointeur de type char qui pointe que le premire caractère de la chaine. Donc coté alouement çà va, c'étais çà ma priorité première ... maintenant alouer directement l'objet bah pourquoi pas.

Citation:
Mais effectivement, tout dépend de ses besoins en Respawn, j'imagine que s'ils sont vraiment massifs, le recours à un OnHeartBeat est moins coûteux.
Ben en comptant les 350 zones oui le delay à du mal chez moi ...
Et puis je ne peux pas dire de faire getarea(), mon area comme tu dis travaille déjà. Car elle travaille via une sorte de garbage collector qui supprime les drops et objets posés.

D'ou l'idée m'est venu de passer aussi par des heartbeat, car le fait est que je parcour la zone, si c'est un item ou un placable de type sac de drop je les traite, si c'est un objet de type waypoint alors je regarde si c'est un waypoint de type respawn alors traitementq.

Donc je me suis dis à raison je pense que cela est bien moins dommageable non? Autant faire d'une pierre deux coups, qu'en dis-tu?
Lien direct vers le message - Vieux
Sire Pom-pom
Roi
 
Avertissement: tout ce qui suit n'est que mon opinion qui vaut ce qu'elle vaut, même quand j'ai l'air sûr de mon fait .

Je ne crois pas que cela aie grand chose à voir avec une différence de performance entre un DelayCommand et l'utilisation du heartbeat. Tes deux "versions" n'ont pas du tout le même design d'après ce que je comprends, donc tu ne peut pas les comparer. Dans un cas, celui que tu utilises maintenant, si j'ai bien compris, tu signales la mort de chaque créature à ton Spawnmaster par un moyen ou par un autre (UdE ou simplement un SetLocal), et par le biais d'un seul Onheartbeat tu respawn les créatures. Dans l'autre cas le respawn des créatures est directement lié à leur onDeath je suppose. Ces deux design n'ont au fond rien à voir avec OnHeartbeat et Delaycommand, tu pourrais te passer totalement de l'OnHeartbeat dans le premier, en recréant les créatures quand un PJ entre dans la zône par exemple, et dans le deuxième cas tu pourrais te passer totalement du DelayCommand, en recréant les créatures immédiatement, ça n'est juste pas là même manière de faire.

Pour l'option 1, parcourir tous les objets d'une zone en Heartbeat, comme tu as l'air de le suggérer (mais je pense que je n'ai pas bien compris) me semble une très mauvaise idée.
Citation:
D'ou l'idée m'est venu de passer aussi par des heartbeat, car le fait est que je parcour la zone, si c'est un item ou un placable de type sac de drop je les traite, si c'est un objet de type waypoint alors je regarde si c'est un waypoint de type respawn alors traitementq.
L'information que tu passe à la matrice lors du OnDeath (en fait quelle créature est morte tout simplement, et ce sous une forme ou une autre, par exemple un entier, en créant un pseudo tableau sur la matrice) doit te permettre de faire les respawns par elle même. Et encore une fois cela n'a rien à voir avec le OnHeartBeat, tu pourrais accrocher le script de respawn à n'importe quel événement.

Pour ce qui est de l'option 2, et de ton script en particulier,
Ton DelayCommand n'était pas du tout optimisé, comme le remarquait Jedaï, toutes ces variables sont copiées en mémoires:
oSpawnMaster; szMonsterTag; nLength; szSpawnPointTag; szSpawnPointInfo; szMonsterClass; oSpawnPoint; fSpawnTime; lSpawnPoint;

Quand tu fais un SetLocalString tu crées une copie de la chaîne en mémoire, puis tu récupères un pointeur: si ton pointeur pointait n'importe où, ça te ferais une belle jambe de le récupérer. Je doute que SetLocalObject crée une copie de l'objet...

Par ailleurs si je peux me permettre quelques remarques d'ordre général, tout l'intérêt d'avoir une matrice comme le RespawnMaster que tu as créé est de minimiser la nécessité d'échanger, et d'aller pêcher (GetObjectByTag) des informations, tout ce qui est lieu de respawn, laps de temps avant le respawn, ResRef de la créature devrait être dans les scripts de la matrice et pas dans ceux de la créature... Et tu ne devrais avoir recours qu'à des OBJECT_SELF, ou des GetLocal...(OBJECT_SELF,...) pour récupérer les informations. Pour récupérer la matrice sur chaque créature, si tout ce qu'elle fait ce sont les respawns, tu ne peux pas vraiment optimiser, car il faudra de toute façon que tu ailles la chercher une fois par un GetObjectByTag(...). Mais quite à ce qu'elle les respawns elle devrait aussi les créer la première fois, auquel cas un simple:
Code PHP:
       object oCreature CreateObject....
       
SetLocalObject(oCreature,"Mat"OBJECT_SELF); 
Te permets d'avoir une référence directe à la matrice sur les créatures, c'est pas avec un SetLocalObject par créature que tu vas réussir à remplir ta mémoire... ce qui est important c'est le gain CPU je pense.

ensuite tu fais par exemple un
Code PHP:
SignalEvent(GetLocalObject(OBJECT_SELF,"Mat"), EventUserDefined(nLeCodePourLaMortDeTaCréature)); 
Et tous le reste, y compris le DelayCommand, si c'est comme ça que tu veux faire, est dans l'UDE de la matrice, en toute lettre pour ce qui est des ResRef et autre truc du genre.

Pour le

Citation:
Ce qui induit que cela bloque les respawn suivant dans la file si le précédent n'est pas fini. Donc en plus si ils n'ont pas la même durée de spawn ..
Comprend pas, de toutes façon un seul script est exécuté à la fois, ça n'a rien de spécifique au DelayCommand, ça ne bloque rien comme le prouve le fait que nwscript fonctionne, et je ne comprend pas ce que tu veux dire par "durée de spawn";
Lien direct vers le message - Vieux
Avatar de Hidwulf
Hidwulf
Roi
 
Avatar de Hidwulf
 
Pas vraiment ... je m'expliquer car je l'ai mal fait.

J'ai du utiliser les demaycommands pas longtemps du tout. Pourquoi? Car mes éboueur de zones parcourent les objet dans la zones, et il passent forcément par un mes waypoints de respawn (qui oui au passage sont bien en pointeur de nom en stockage de chaine de caractère sinon il est vrai que le proc aurrait bien du mal). Et donc pourquoi ne pas faires les traitement de respawn sur le waypoint de respawn une fois tombé dessus?

Car en effet les eboueurs d'area sont execute suivant des hearbeat, là je ne sais pas si vous avez qqch de mieux je suis prenneur sinon, et ainsi je couple le traitement des suppressions des drops au respawn. Maintenant à savoir si cela est plus pratique que de mettre des flags ...

Pour ma durée de respawn, en fait la durée de respawn d'un montre varie en fonction du monstre lui-même forcément mais aussi de son lieu. Par exemple, plus on s'enfonce dans une crypte, plus le respawn est rapide et donc la difficulte de même. Et le fait qu'il faudrait alors mettre dans la palette plusieurs copies des monstres dont la durée de spawn varie? Bah çà ne me tente pas trop vu déjà que les métiers tels que forgeron, bijoutier prennent énormément d'objet dans la plalette (enorme c'est énorme ...)

Donc je ne sais pas mais je n'ai pas d'autre moyen que de lier çà a un waypoint, qui contient les infos adéquoites et donc variables selon les cas.

Je posterai un de ces quatre le respawn que j'utilise pour "recevoir" vos amélioration, moi je suis toute ouie )
Lien direct vers le message - Vieux
Avatar de Hidwulf
Hidwulf
Roi
 
Avatar de Hidwulf
 
Le voilà mon script
Le script via delay n'etait pas le mien mais celui de nwnvault datant de septembre, voilà celui que j'ai fait en fonction de mes besoins :

Code PHP:
//::///////////////////////////////////////////////
//:: Spawn-Heartbeat-ResRef
//:: hidwulf_spawn
//:: Copyright (c)
//:://////////////////////////////////////////////
/*
    Ce script vous permet de faire respawner une creature
    selon le temps, un resref et un waypoint.
    MAGIQUE!!!

    le waypoint a placer
    => nom: XXXX_resref, ou XXXX est la duree de
    temps de respawn de la creature sur 4 chiffres
    unite le heartbeat = 6 secondes. Ainsi il y'a un
    décompte de hearbeat en somme.
    => tag: ms_xxx, le tag doit commencer par ms, le
    on s'en fout c'est pour vous ou la comprehension
    => Avec ce système plus besoin de "poser" les
    monstres dans la zone, cela se fera automatiquement.
    Gain de place considérable. On est passe chez
    moi d'une reduction de 10Mo du mod. Mais forcément
    au chargement du module, l'usage du cpu est assez
    important pendant les 2 premières minutes, apres
    c'est du tout bon : 
        usage cpu a vide (de joueur) : 30%-52%
    A noter que si je remplace a peu près le tout par des
    delaycommand je fais du 32-55%, mais avec des spikes
    (des pics et descentes) qui atteignent les 75% a
    intervals constants ...    

    Voila bon spawn!!!
*/

//::///////////////////////////////////////////////
//:: SignalerMort_oWay
//:://////////////////////////////////////////////
/*
    A mettre dans l'evenement OnDeath du monstre
    dans la palette
*/
//:://////////////////////////////////////////////
//:: Created By: Hidwulf
//:: Created On: 15/10/2002
//:://////////////////////////////////////////////
void SignalerMort_oWayobject oMonstre)
{
    
object oWay GetLocalObject(oMonstre,"oWay");
    if ( 
GetIsObjectValid(oWay) )
    {
        
SetLocalInt(oWay,"Vie",0);
    }
}

//::///////////////////////////////////////////////
//:: Spawner_oWay
//:://////////////////////////////////////////////
/*
    Permet de faires spawner les monstres de
    facon dynamique.
    Version ici qui va parcourir les waypoints
    de la zone et que ceux-ci.
*/
//:://////////////////////////////////////////////
//:: Created By: Hidwulf
//:: Created On: 15/10/2002
//:://////////////////////////////////////////////
void  Spawner_oWay object oArea )
{
    
location baseloc Location(oArea,Vector(),0.0);
    
int counter=1;
    
object oWay GetNearestObjectToLocation(OBJECT_TYPE_WAYPOINT,baseloc,counter);
    while ( 
oWay != OBJECT_INVALID )
    {
        if ( 
GetSubString(GetTag(oWay),0,3) == "ms_" )  /* waypoint de spawn */
        
{
            if ( 
GetLocalInt(oWay,"Vie") == /* Si monstre rattache mort */
            
{
                
string nom GetName(oWay);
                
int temps GetLocalInt(oWay,"Dcpt")-1;
                if ( 
temps <= /* Si le decompteur est a 0 */
                
{
                    
/* Realloue le temps de respawn */
                    
SetLocalInt(oWay,"Dcpt",StringToInt(GetSubString(nom,0,4)));
                    
int taille GetStringLength(nom) - 5;
                    
object oCreature CreateObject(OBJECT_TYPE_CREATURE,GetSubString(nom,5,taille),GetLocation(oWay));
                    
SetLocalObject(oCreature,"oWay",oWay);
                    
//SetLocalString(oCreature,"oWay",GetTag(oWay));
                    /* Indique que le monstre est vivant */
                    
SetLocalInt(oWay,"Vie",1);
                }
                else 
// Il n'est pas encore le temps de respawn pour le monstre
                
{
                    
SetLocalInt(oWay,"Dcpt",temps);
                }
            }
        }
        
counter++;
        
oWay GetNearestObjectToLocation(OBJECT_TYPE_WAYPOINT,baseloc,counter);
    }

La par contre si vous avez des remarques à faire je veux bien car je suis près à faire toute modifications me permettant de soulager le cpu du serveur et dieu sait qu'il en a besoin le bougre.
Je préfère de loin que vous critiquez quelque chose que j'ai fait moi-même et que j'utilise

Merci de me dire si il y a mieux ou si il est possible de pouvoir optimiser certaines choses.
Lien direct vers le message - Vieux
Avatar de ruru2a
ruru2a
Alpha & Oméga
 
Avatar de ruru2a
 
Unhappy
pourriez vous m'eclairer
Ce systeme a l'air interressant, car j'utilise par exemple dans les tavernes des pnj ki font des actions au hazard, histoire de mettre un pe d'embiance.

Donc ma kestion est :

Si j'utilise c scripts sont il sensés couper les OHB de mes pnj de chake tavernes (ya d'autres pnj aussi mais on s'en fiche pour l'exemple), a partir du moment ou les joueurs ne sont plus dans la zone, ou bien faut il modifier les scripts (Azrael) pour que ceux-ci marchent avec mon module ???

en bref le script d'azrael est il un script generik ki fonctionne avec chake module ou fo t'il faire une modif pour les OHB ?
Lien direct vers le message - Vieux
Avatar de Jaha Effect
Jaha Effect
Alpha & Oméga
 
Avatar de Jaha Effect
 
On a une taverne fabuleuse sur le forum, avec de l'ambiance a plus savoir quoi en faire que même les ricains du vault nous envie?
Et toi tu te demande comment mettre un peu d'ambiance...
Y'a des fois je me demande pourquoi on se fait *****.

Jaha Effect
Lien direct vers le message - Vieux
Avatar de 'Az
'Az [P.H.]
Alpha & Oméga
 
Avatar de 'Az
 
ah no problem, normalement il te suffis de mettre le second script que j'ai donné (celui du haut par le message de Tynril est bidon) dans le OnEnter de la zone, et un autre dans le OnExit, et de remplir le code dans la fonction OnHeartBeat.
Lien direct vers le message - Vieux
Avatar de ruru2a
ruru2a
Alpha & Oméga
 
Avatar de ruru2a
 
ok dans le On Load du module on fé plus rien, je prends t 2 script pour le enter area et exit area, le seul truc ke je comprends pas c le code ??? kel code ???

ps : je c ke je suis mauvais
Lien direct vers le message - Vieux
Avatar de 'Az
'Az [P.H.]
Alpha & Oméga
 
Avatar de 'Az
 
bien je parle du code que tu aurais mis dans ton OnHeartBeat.

au lieux de le mettre sur l'évenement OnHeartBeat de ton area, ou de n'importe quoi, tu le met

Code PHP:
void OnHeartBeat()
{
    if(!
GetLocalInt(OBJECT_SELF"nbrPC")) return;

    
//ICI !!!!!

    
DelayCommand(6.0fOnHeartBeat());//On active le script qui definira l'action

ca va mieux ?
Lien direct vers le message - Vieux
Avatar de ruru2a
ruru2a
Alpha & Oméga
 
Avatar de ruru2a
 
J'avoue (au risk de paraitre lourd) ke je comprends pa comment ca peut marcher...

exemple : dans le OHB des pnj d'une taverne, g mis un script ki leur fait faire des actions aleatoires (boire, etre saoul, dormir...). Si je te suis je dois enlever ce script des pnjs et le mettre la ou tu me l'indike. Cependant, comment mes pnj vont etre affectés ??? Honnetement je capte pas du tout...
Lien direct vers le message - Vieux
Avatar de ruru2a
ruru2a
Alpha & Oméga
 
Avatar de ruru2a
 
Azrael me laisse pas tomber stp !!!
Lien direct vers le message - Vieux
Fil fermé
Les forums JOL > Forum jeux-vidéo > Neverwinter Nights > NWN - Maskado > [Script] Emulation de l'évènement OnHeartBeat avec moins de charge CPU
   

Outils Rechercher
Rechercher:

Recherche avancée

Les vidéos de Neverwinter Nights RSS
  • Aucune vidéo pour le moment...
Thème visuel : Fuseau horaire GMT +1. Il est actuellement 05h14.
   

© JeuxOnLine, le site des MMO, MMORPG et MOBA. Tous droits réservés. - Conditions générales d'utilisation - Conditions d'utilisation des forums - Traitement des données personnelles - ! Signaler un contenu illicite