Temps de chargement avant le match vs temps de chargement du jeu

9

Je développe un jeu dans lequel un labyrinthe aléatoire est inclus.
Il y a des créatures IA qui se cachent dans le labyrinthe. Et je veux qu'ils aillent dans un certain chemin en fonction de la forme des labyrinthes.

Maintenant, il y a deux possibilités pour moi de mettre en œuvre cela, la première façon (que j'ai utilisée) est de calculer plusieurs chemins cachés une fois le labyrinthe créé.
La seconde consiste à calculer un chemin qui devait être calculé une fois, quand une créature commence à le rôder.

Ma principale préoccupation est le temps de chargement. Si je calcule de nombreux chemins lors de la création du labyrinthe, le temps de pré-chargement est un peu long, j'ai donc pensé à les calculer en cas de besoin.
Pour le moment, le jeu n'est pas «lourd», donc le calcul des chemins en milieu de partie n'est pas perceptible, mais je crains que ce ne soit plus compliqué.

Toutes suggestions, commentaires, opinions seront utiles.

Éditer:

Pour l'instant, psoit le nombre de chemins pré-calculés, une créature a la probabilité de 1/pprendre un nouveau chemin (ce qui signifie un calcul de chemin) au lieu d'un chemin existant.
Une créature ne commence sa patrouille que lorsque le chemin est entièrement calculé, donc pas besoin de s'inquiéter de sa mort dans le processus.

Gardien
la source
8
À ce stade, ce serait une pré-optimisation. Je le laisserais tel quel jusqu'à ce qu'il y ait un problème.
John McDonald
3
Et pour caresser un peu avec @JohnMcDonald, si vous pouvez calculer ces chemins en milieu de partie et ce n'est pas perceptible, quel facteur contributif peuvent-ils être au moment du chargement?
James

Réponses:

6

BerickCook a correctement exprimé l'idée. Laissez les calculs où ils sont s'ils fonctionnent correctement maintenant.

Si vous pouvez faire le calcul avant et que vous êtes sûr que vous n'en aurez pas besoin en milieu de partie, faites-le avant. Sinon, faites-le après le chargement. Si le calcul pendant le jeu est imperceptible, vous pouvez le faire à cet endroit. Si à un moment donné la complexité évolue et les calculs deviennent trop lourds, commencez à optimiser.

Mais une chose: si vos calculs sont mis en œuvre pour fonctionner en milieu de partie, vous pouvez toujours les forcer à être exécutés pendant le chargement de toute façon.

Il existe de nombreuses solutions:

  • calculer / charger les chemins lors de la création / chargement de niveau
  • utiliser un deuxième fil pour calculer les chemins
  • optimisez vos algorithmes
  • utilisez un système interruptible si vous n'avez pas accès au filetage.

J'ai vu et utilisé la dernière option dans un jeu grand public. Assurez-vous simplement de sauvegarder correctement toutes les données nécessaires à la reprise du calcul et vérifiez régulièrement le temps / les opérations restants pendant le calcul.

Selon votre cas, le système interruptible pourra donner des solutions préliminaires et partielles qui pourront être utilisées événement avant la fin du calcul.


Modifier : répondre à @Keeper

"L'algorithme interruptible" n'était utile qu'en raison des contraintes que nous avions. Fondamentalement, nous avons pallié au manque de multithreading.

À un moment donné, nous avions un jeu où l'IA devait calculer de grandes quantités de mouvements sur la base de plusieurs dictionnaires. Pendant ce calcul, toutes les animations s'arrêtaient car les dictionnaires étaient étendus avec plus de données et l'ensemble de données contenant les données était modifié et moins efficace lorsque le jeu était adapté pour le multijoueur (où l'IA devait interagir même pour les mouvements du joueur). Nous n'avions qu'un seul thread disponible pour la boucle de jeu (l'impératif étant que le code multi-plateforme doit s'exécuter sur toutes les plateformes prises en charge). À ce stade, il a été décidé de casser l'algorithme de calcul afin de pouvoir l'interrompre. Par conséquent, nous ne pouvions pas simplement utiliser le système récursif qui était en place car les variables ne pouvaient pas être enregistrées. Les fonctions ont été remplacées par des objets qui contenaient simplement toutes les variables et pointeurs nécessaires vers les objets parents et enfants. Je ne '

  • enregistrer l'état de ses calculs actuels
  • interrompre à la fin d'une boucle ou pendant une boucle (lorsqu'un objet enfant interrompt)
  • sortir quand le temps est écoulé
  • reprendre là où il s'est arrêté soit en redémarrant une boucle à l'index de droite, soit en appelant l'objet enfant actuellement en haut de sa pile enfants.
  • tout nettoyer si le calcul est interrompu
  • donner le meilleur résultat partiel.

Seules les opérations les plus coûteuses ont été divisées en objets séparés et il a fallu un certain temps pour trouver les bons endroits où nous pouvions arrêter les calculs, mais au final cela fonctionne très bien.

Nous avons perdu des performances, mais les performances perçues étaient bien meilleures pour l'utilisateur car les animations se déroulaient sans problème sur toutes les plates-formes, toutes les plates-formes pouvaient alors utiliser les plus grands dictionnaires sans souffrir d'animations saccadées ou de gels. Cela nous a également permis d'exécuter plusieurs instances en parallèle lorsque nous en avions besoin plus tard.

Bien sûr, maintenant, sur l'iPhone et l'iPad, le jeu n'en a plus besoin, l'utilisation d'un deuxième fil serait idéale. Mais je soupçonne que le code est toujours là.

Coyote
la source
Merci, cela semble très intéressant. Pouvez-vous expliquer le concept de «système interruptible» (pourquoi et comment)? (googler ce n'était pas si utile ..). J'ajouterai quelques détails à la question.
Keeper
@Keeper J'espère avoir répondu à votre question sur la partie interruptible. C'est pénible à faire et ce n'est pas pertinent sur la plupart des systèmes modernes.
Coyote
Même si je ne vais pas utiliser cette méthode pour l'instant, vous m'avez ouvert les yeux sur quelque chose de nouveau. Votre réponse mérite d'être acceptée.
Keeper
8

Pour l'instant, comme le calcul des chemins en milieu de partie est imperceptible, c'est l'approche idéale. Si / quand il arrive au point où le jeu est interrompu par les calculs, passez-le en calculant les chemins avant le chargement du niveau.

Les temps de chargement initial plus longs sont pardonnables, mais les fluctuations FPS aléatoires pendant le jeu ne le sont généralement pas.

BerickCook
la source
2

Une possibilité si vous en avez besoin est de déplacer les calculs vers un deuxième thread car presque tous les PC ont plus d'un cœur de processeur de nos jours.

Le processus de base serait:

  • Lorsqu'une créature demande un chemin, ajoutez la demande à une file d'attente de requêtes sécurisée pour les threads et signalez le thread.
  • La créature reste inactive en attendant que le thread libère l'entrée de cette file d'attente, la traite et la place sur une liste complète.
  • Chaque image vérifie la liste complète du fil principal et attribue des chemins terminés aux créatures.

Vous devez également faire attention à quelques cas supplémentaires (par exemple, si la créature meurt avant que la demande ne soit traitée).

Adam
la source
2
Si vous ne souhaitez pas introduire le filetage, vous pouvez également calculer votre chemin de manière incrémentielle (par exemple, calculer certaines étapes à chaque image).
bummzack