Installation à la demande pour les jeux

Cet article technique aborde deux techniques, l’installation à la demande et l’installation en arrière-plan, à l’aide de Windows Installer. Les jeux peuvent utiliser ces techniques d’installation pour offrir une expérience de jeu améliorée et plus agréable pour les joueurs en réduisant le temps d’installation.

Vue d’ensemble

L’installation a été un élément des applications basées sur l’ordinateur depuis longtemps. La plupart des applications nécessitent aujourd’hui qu’elles soient installées sur le disque dur local de l’utilisateur avant de pouvoir être utilisées. Les jeux d’ordinateurs ne font pas exception ; Lorsqu’un consommateur achète un jeu Microsoft Windows et tente de l’exécuter, il doit d’abord suivre un processus d’installation qui copie les fichiers nécessaires du disque du jeu vers le disque dur. Ce processus d’installation est généralement long et peut prendre jusqu’à une heure. Le temps d’installation est un facteur qui rend les jeux de console plus souhaitables que les jeux basés sur ordinateur pour certains lecteurs, car ils sont en mesure de lire immédiatement un jeu de console après avoir inséré le disque du jeu. La technologie abordée dans cet article va tenter de résoudre ce point en réduisant considérablement le temps d’installation.

En règle générale, les jeux nécessitent l’installation de la totalité ou de la plupart des fichiers avant leur lancement. Pour permettre l’installation à la demande, les ressources du jeu doivent être modulaires. autrement dit, le développeur doit diviser les ressources de l’application (graphiques, audio, etc.) en composants. Chaque composant est un ensemble de ressources qui peuvent être installées ou supprimées en tant qu’unité. Une fois cette opération effectuée, le développeur de jeux définit une ou plusieurs fonctionnalités, en général un ou plusieurs par niveau ou zone. Chaque fonctionnalité d’une application spécifie un ensemble de composants nécessaires à l’exécution de cette fonctionnalité particulière. Lorsqu’une application est installée, ses fonctionnalités peuvent être marquées « installer » (composants copiés sur le disque dur local au moment de l’installation) ou « publiées » (composants copiés sur le disque dur local après l’installation initiale lorsque l’application utilise cette fonctionnalité). Un développeur de jeux peut réduire le temps d’installation en concevant le jeu pour le lancer et l’exécuter avec un ensemble minimal de fonctionnalités installées. Le reste de ses fonctionnalités peut être marqué comme publié et installé à la demande lorsque l’application doit réellement utiliser des fonctionnalités fournies par ces fonctionnalités.

Les jeux peuvent appeler Windows Installer pour installer une fonctionnalité particulière qui n’a peut-être pas été installée. Pour que l’installation s’affiche en arrière-plan, un thread de travail peut être utilisé pour effectuer les appels au programme d’installation pendant que le thread principal continue à gérer la logique de jeu et à afficher l’écran. Cela réduit le risque d’interruption de jeu provoqué par l’installation. Le jeu peut lancer l’installation à tout moment. Toutefois, étant donné que l’installation consomme des cycles de processeur, il n’est généralement pas judicieux de procéder à l’installation lorsque le thread principal est un besoin essentiel de la puissance de traitement, par exemple lorsque l’utilisateur se trouve au milieu de l’action. Par exemple, un bon moment pour effectuer l’installation peut être pendant le moment où l’utilisateur se trouve dans le menu jeu, lorsque le jeu est suspendu ou réduit, ou lorsque l’utilisateur regarde le film de présentation ou cutscenes.

Prise en charge des correctifs

La plupart des jeux doivent être mis à jour même après avoir été fournis à mesure que des bogues sont résolus et que de nouvelles fonctionnalités sont ajoutées. La mise à jour nécessite souvent des correctifs, ce qui est généralement une procédure simple pour les jeux. Étant donné que tous les fichiers nécessaires sont installés sur le disque dur de l’utilisateur, la mise à jour corrective d’un jeu implique la copie des fichiers modifiés sur le disque dur, en remplaçant les fichiers existants. Lorsque l’installation à la demande est utilisée, tous les fichiers ne sont pas installés et copiés au moment de la mise à jour corrective. Par conséquent, le patcher ne peut pas simplement écrire des fichiers mis à jour dans le dossier du jeu.

Windows Installer possède des fonctionnalités permettant d’appliquer des correctifs aux applications qui utilisent Install-on-demand. Lors de l’application d’un correctif, le programme d’installation met en cache le correctif sur le système. Cette fonctionnalité fonctionne bien pour les correctifs avec de petits deltas. Les fichiers initialement publiés n’ont plus besoin d’être sur le disque au moment de la mise à jour corrective, de sorte que ces fichiers peuvent être publiés. Plus tard, lorsque l’application s’exécute et doit accéder aux fichiers, le programme d’installation installe la version la plus récente de ces fichiers en copiant la version publiée à l’origine à partir du média (par exemple, CDs) et en appliquant le correctif après avoir lu les données de correctifs enregistrées.

Exemple du kit de développement logiciel (SDK) InstallOnDemand

L’exemple Install-on-demand pour les jeux illustre les techniques d’installation à la demande décrites dans cet article. Contrairement à d’autres exemples, l’installation à la demande pour les jeux ne peut pas être exécutée directement à partir de l’exemple de navigateur. Étant donné que l’exemple utilise la Windows Installer pour gérer son installation, il doit être inclus dans la base de données des applications installées du programme d’installation.

Pour lancer l’exemple

  1. Utilisez le lien installer le projet dans l’exemple de navigateur pour copier les fichiers de l’exemple dans un dossier.
  2. Double-cliquez sur InstallOnDemand.msi pour installer l’exemple.
  3. Sélectionnez installation par défaut.
  4. Démarrez l’exemple en lançant l' InstallOnDemand.exe dans le dossier installed (généralement Program Files \ InstallOnDemand) ou en lançant des programmes dans le menu démarrer \ .

InstallOnDemand.msi est une base de données reconnue par le programme d’installation. Il définit l’ensemble du processus d’installation : la structure de répertoires, ce qui va et ne sera pas copié, les ressources qui seront copiées ensemble, les valeurs de Registre à écrire, les raccourcis à créer, etc.

Lorsqu’il est lancé, l’exemple lit une séquence d’introduction. Le joueur peut l’arrêter et entrer dans le menu principal en appuyant sur la touche ÉCHAP. À la suite de l’introduction, le joueur peut démarrer un nouveau jeu en entrant un nom de caractère et en faisant défiler les statistiques. Avant que l’exemple commence à lire la séquence d’introduction, l’exemple appelle une fonction installer pour vérifier si la fonctionnalité pour le niveau 1 est installée. Si la fonctionnalité de niveau 1 n’a pas été installée, l’exemple utilise un thread d’arrière-plan pour demander au programme d’installation d’installer le jeu, tandis que le thread principal fait autre chose (par exemple, en lisant la séquence d’introduction, en affichant le menu ou en interagissant avec le joueur lors de la création de caractères). L’expérience est différente de l’installation d’un jeu traditionnel dans la mesure où l’utilisateur est occupé dans le jeu (en regardant l’introduction ou en créant un nouveau caractère) pendant l’installation. Une fois que le joueur a fini de créer un caractère, l’exemple charge les ressources pour le niveau 1.

Sur le côté droit de l’écran d’exemple se trouvent cinq boutons marqués « niveau de lecture 1 » à « niveau de lecture 5 ». Ces boutons simulent l’achèvement du joueur du niveau actuel et avancent jusqu’au suivant. Quand l’utilisateur clique sur l’un de ces boutons, un écran de statistiques s’affiche pour afficher des informations sur le niveau qu’il vient de terminer. L’exemple prend également cette heure pour demander au programme d’installation de vérifier et d’installer le niveau suivant, s’il n’est pas déjà installé. L’installation se produit pendant que le lecteur lit l’écran des statistiques, de sorte que lorsque l’utilisateur clique sur OK pour passer au niveau suivant, les ressources du niveau sont installées et prêtes à être chargées.

Fonctionnalités et composants de l’exemple

En règle générale, les jeux nécessitent l’installation de la totalité ou de la plupart des fichiers avant leur lancement. Pour permettre l’installation à la demande, les ressources du jeu doivent être modulaires. autrement dit, le développeur doit diviser les ressources de l’application (graphiques, audio, etc.) en composants. Chaque composant est un ensemble de ressources qui peuvent être installées ou supprimées en tant qu’unité. Une fois cette opération effectuée, le développeur de jeux définit une ou plusieurs fonctionnalités, en général un ou plusieurs par niveau ou zone. Chaque fonctionnalité d’une application spécifie un ensemble de composants nécessaires à l’exécution de cette fonctionnalité particulière. Lorsqu’une application est installée, ses fonctionnalités peuvent être marquées comme étant « installées » (composants copiés sur le disque dur local au moment de l’installation) ou « publiées » (composants copiés sur le disque dur local lorsque l’application utilise ultérieurement cette fonctionnalité). Un développeur de jeux peut réduire le temps d’installation en concevant le jeu pour qu’il démarre et s’exécute avec un ensemble minimal de fonctionnalités installées. Le reste de ses fonctionnalités peut être marqué comme publié et installé à la demande lorsque l’application doit réellement utiliser des fonctionnalités fournies par ces fonctionnalités.

Le tableau suivant répertorie les six fonctionnalités de niveau supérieur que l’exemple définit.

Nom de la fonctionnalité Fonctionnalités Composants Fichiers
Core Comprend les ressources requises à tout moment, quel que soit le niveau. Ces ressources sont les suivantes : exemple d’exécutable, média requis par la séquence d’introduction et le chargement de l’écran, et fichier. FX qui gère tout le rendu dans l’exemple. Core InstallOnDemand.exe, InstallOnDemand. FX, Loading.bmp, Level. x
Core (identique à ci-dessus) CoreUI Interface utilisateur multimédias \ \ dxutcontrols. DDS, Media \ UI \ DXUTShared. FX, Media \ UI \ Arrow. x
Core (identique à ci-dessus) CoreMisc Médias \ divers \ de la bande. x, media \ misc \seafloor.bmp
Core (identique à ci-dessus) CoreSpeeder Support \ PRT-démo \ Landshark. x, Media \ PRT Demo \ _diff.jpg
Core (identique à ci-dessus) CoreReg N/A (valeur de registre)
Level1 Fournit les ressources utilisées par le niveau 1. Level1 Level1.jpg
Level1 (identique au précédent) L1Skybox \Sondes de lumière multimédias \ Galileo _ Cross. DDS
Level2 Fournit les ressources utilisées par le niveau 2. Level2 Level2.jpg
Level2 (identique au précédent) L2Skybox Traversée de l’analyse Media \ Light sondes \ _ Cross. DDS
Level3 Fournit les ressources utilisées par le niveau 3. Level3 Level3.jpg
Level3 (identique au précédent) L3Skybox \Sondes de lumière multimédia \ RNL _ Cross. DDS
Level4 Fournit les ressources utilisées par le niveau 4. Level4 Level4.jpg
Level4 (identique au précédent) L4Skybox \Sondes de lumière multimédia \ stpeters _ Cross. DDS
Level5 Fournit les ressources utilisées par le niveau 5. Level5 Level5.jpg
Level5 (identique au précédent) L5Skybox \Sondes de lumière multimédia \ Uffizi _ Cross. DDS

 

Les fonctionnalités de niveau1 à Level5 possèdent des sous-fonctionnalités supplémentaires qui contiennent des fichiers qui ne sont pas directement utilisés par l’exemple. Ces fichiers de sous-fonctionnalités ont été ajoutés pour que l’installation soit plus longue. Cela permet d’illustrer l’opération d’installation en cours qui s’exécute en arrière-plan pendant l’exécution de l’exemple.

Le tableau suivant répertorie les sous-fonctionnalités.

Fonctionnalité Sous-fonctionnalités Fichiers
Level1 L1PH1, L1PH2, L1PH3, L1PH4, L1PH5 Données d’espace réservé de niveau1 \ L1PH1. dat niveau1 données de l’espace réservé \ L1PH2. dat de niveau1 données de l’espace réservé \ L1PH3. dat de niveau1 données d’espace réservé \ L1PH4. dat de niveau1 données \ L1PH5. dat
Level2 L2PH1, L2PH2, L2PH3, L2PH4, L2PH5 Données d’espace réservé de d’isolement2 \ L2PH1. dat D’isolement2 données d’espace réservé \ L2PH2. dat d’isolement2 données d’espace réservé \ L2PH3. dat d’isolement2 données d’espace réservé \ L2PH4. dat D’isolement2 données d’espace réservé \ L2PH5. dat
Level3 L3PH1, L3PH2, L3PH3, L3PH4, L3PH5 Données de l’espace réservé de niveau3 \ L3PH1. dat données des espaces réservés du niveau3 \ L3PH2. dat niveau3 données de l’espace réservé \ L3PH3. dat niveau3 données d’espace réservé \ L3PH4. dat niveau3 données d’espace réservé \ L3PH5. dat
Level4 L4PH1, L4PH2, L4PH3, L4PH4, L4PH5 Données d’espace réservé Level4 \ L4PH1. dat Level4 données d’espace réservé \ L4PH2. dat Level4 données d’espace réservé L4PH3 \ . dat Level4 données d’espace réservé L4PH4 \ . dat Level4 données d’espace réservé L4PH5 \ . dat
Level5 L5PH1, L5PH2, L5PH3, L5PH4, L5PH5 Données d’espace réservé Level5 \ L5PH1. dat Level5 données d’espace réservé \ L5PH2. dat Level5 données d’espace réservé L5PH3 \ . dat Level5 données d’espace réservé L5PH4 \ . dat Level5 données d’espace réservé L5PH5 \ . dat

 

Pendant l’installation, la fonctionnalité de base doit être marquée comme « install » et toutes les autres fonctionnalités doivent être marquées « publié ». En installant une seule fonctionnalité au lieu de six, le temps que le joueur doit attendre jusqu’à ce que le jeu se lance soit considérablement réduit.

Installation

L' Windows Installer fournit un mécanisme permettant à une application de demander l’installation d’une fonctionnalité publiée. Toutefois, le mécanisme est un appel d’API (Application Programming Interface) synchrone, ce qui signifie que l’application doit attendre à l’intérieur de l’appel jusqu’à ce que l’installation soit terminée. Pour obtenir une installation en arrière-plan, un thread de travail est requis afin que le thread d’application principal soit libre d’effectuer d’autres tâches importantes, telles que le rendu à l’écran pour continuer à fournir des commentaires visuels sur le lecteur.

Dans l’exemple, il existe trois États d’installation qui se produisent pendant l’exécution de l’exemple : installation active, installation passive et aucune installation.

  • L’installation active est une demande initiée par l’exemple lorsqu’il doit accéder aux ressources fournies par une ou plusieurs fonctionnalités, ou les charger. L’exemple effectue cette opération lorsqu’il ne peut pas continuer tant que la ressource n’est pas installée.
  • L’installation passive est lancée lorsque l’exemple n’effectue pas une tâche critique, par exemple quand le joueur est dans un menu ou regarde une scène coupée. Dans ce cas, le thread de travail vérifie si une fonctionnalité de l’exemple est encore publiée. S’il en trouve un, il appelle le programme d’installation pour installer cette fonctionnalité. Ce processus se répète jusqu’à ce que toutes les fonctionnalités de l’exemple soient installées. Fondamentalement, l’installation passive utilise des cycles de processeur supplémentaires pour effectuer l’installation en arrière-plan quand elle est la moins intrusive pour l’exemple principal.
  • Aucune installation ne se produit lorsque le joueur est activement engagé dans le jeu ; Cela empêche une chute de fréquence d’images qui perturberait l’expérience utilisateur.

Dans l’exemple, une classe CMsiUtil est définie pour gérer toutes les tâches liées à l’installation. Fondamentalement, CMsiUtil utilise un thread de travail qui appelle le programme d’installation pour installer les fonctionnalités de l’exemple dans une boucle. La classe a deux files d’attente qui stockent les demandes d’installation : une file d’attente à priorité élevée pour une installation active et une file d’attente basse priorité pour une installation passive. Pendant l’initialisation, la classe énumère toutes les fonctionnalités du produit et les ajoute à la file d’attente d’installation passive. Étant donné que la totalité du produit est mise en file d’attente de cette manière, le produit entier finira par être installé si l’exemple a suffisamment de cycles de processeur libres.

Lorsque l’exemple doit demander une installation active, l’exemple peut appeler CMsiUtil :: UseFeatureSet () et passer le nom de la fonctionnalité de niveau supérieur. UseFeatureSet () met en file d’attente la fonctionnalité demandée et toutes ses sous-fonctionnalités dans la file d’attente d’installation active afin que le thread de travail puisse les installer.

Lors de l’exécution d’une demande d’installation, le thread de travail vérifie la file d’attente d’installation active ainsi que la file d’attente d’installation passive pour déterminer si l’une ou l’autre des demandes supplémentaires est associée à une file d’attente. Chaque fois que le thread trouve une requête, il appellera l’API du programme d’installation pour effectuer l’installation. Une fois que les deux files d’attente sont vides, le thread de travail passe en mode veille avec un appel à WaitForSingleObject. Étant donné que l’ensemble du produit est placé dans la file d’attente d’installation passive pendant l’initialisation, une file d’attente vide implique que la totalité du produit a été installée.

L’exemple appelle CMsiUtil :: EnablePassiveInstall () pour activer ou désactiver l’installation passive. EnablePassiveInstall (true) incrémente le nombre d’activations pour l’installation passive et EnablePassiveInstall (false) le décrémente. Si le nombre d’activations est supérieur à 0, la classe traitera la file d’attente d’installation passive. L’exemple permet l’installation passive lorsque l’une des conditions suivantes est remplie :

  • L’utilisateur visualise la séquence d’introduction initiale.
  • L’utilisateur navigue dans le menu de l’exemple.
  • L’utilisateur visualise les statistiques à la fin d’un niveau.
  • L’exemple d’application perd son focus et passe à l’arrière-plan.

Les méthodes de CMsiUtil sont répertoriées ci-dessous :

Méthode Description
AbortAllRequests Provoque l’abandon de l’installation en cours et vide la file d’attente des demandes d’installation active.
AbortCurrentRequest Entraîne l’arrêt de l’installation en cours. Le thread de travail traite ensuite la requête suivante dans la file d’attente, le cas échéant.
EnablePassiveInstall Incrémente ou décrémente le nombre d’activations de l’installation passive. L’exemple utilise cet appel pour contrôler le moment où l’installation passive peut et ne peut pas se produire.
GetCurrentFeatureName Retourne le nom de la fonctionnalité qui est installée activement.
GetFeatureProgress Retourne la position de la graduation actuelle pour la fonctionnalité en cours d’installation.
GetFeatureProgressMax Retourne le nombre maximal de cycles de progression pour la fonctionnalité en cours d’installation.
Obtenir la dernière erreur Utilisez cette méthode pour récupérer le code de retour de la demande d’installation précédente.
GetPassiveProgress Retourne la position de la barre de progression pour une installation passive.
GetPassiveProgressMax Retourne la position actuelle du cycle et le nombre maximal de cycles pour une installation passive. Ensemble, l’exemple peut les utiliser pour montrer la progression globale de l’installation passive.
GetProgress Retourne la position de graduation de la barre de progression pour l’installation de l’ensemble de fonctionnalités actif. Utilisé lorsque l’exemple affiche la barre de progression de l’installation. Étant donné que la Windows Installer fournit uniquement des informations de progression pour la fonctionnalité en cours d’installation, la méthode divise la barre de progression parmi les fonctionnalités demandées afin que l’utilisateur puisse toujours voir l’ensemble de l’installation comme une seule tâche.
GetProgressMax Retourne le nombre de cycles de barre de progression maximal pour l’installation de l’ensemble de fonctionnalités actif. Utilisé lorsque l’exemple affiche la barre de progression de l’installation.
Initialiser Initialise la classe avec l’identificateur global unique (GUID) du produit. Cette méthode énumère également chaque fonctionnalité de l’application qui a été publiée mais qui n’est pas encore installée, et la place dans la file d’attente d’installation passive pour configurer l’installation passive.
IsInstallInProgress Utilisez cette méthode pour déterminer si une installation active est en cours de traitement.
UseFeature Méthode privée appelée par UseFeatureSet. Vérifie si une fonctionnalité est installée. Si la fonctionnalité demandée est installée, la méthode retourne. Si la fonctionnalité n’est pas encore installée (publiée), la méthode met en file d’attente une nouvelle demande d’installation active pour le thread de travail, puis retourne. Handle d’événement facultatif qui sera signalé lorsque l’installation demandée est terminée.
UseFeatureSet Appelée par l’exemple lorsqu’il doit accéder aux fonctionnalités fournies par une fonctionnalité particulière ou l’une de ses sous-fonctionnalités. La méthode énumère toutes les fonctionnalités de l’exemple et appelle UseFeature () pour les sous-fonctionnalités de la fonctionnalité racine spécifiée. L’exemple peut passer un descripteur d’événement qui sera signalé lorsque l’ensemble de fonctionnalités est installé. Étant donné que toutes les fonctionnalités sont installées en tant que jeu, le descripteur est spécifié pour la dernière fonctionnalité mise en file d’attente par UseFeature () au lieu de toutes les fonctionnalités, afin que l’exemple soit notifié une fois que toutes les fonctionnalités demandées ont été installées.
UseProduct Met en file d’attente une demande d’installation active pour le thread de travail afin d’appeler le programme d’installation pour effectuer une installation complète du produit. Handle d’événement facultatif qui sera signalé lorsque l’installation demandée est terminée.

 

Limitation

La version actuelle du programme d’installation n’est pas conçue pour un accès simultané par plusieurs threads. Par conséquent, lorsque le thread de travail appelle le programme d’installation, le thread principal ne doit pas appeler le programme d’installation. Un exemple de cette limitation se produit dans l’exemple lorsque le thread principal demande une fonctionnalité, puis demande à nouveau la même fonctionnalité avant que le thread de travail ne termine l’installation. La deuxième demande appelle MsiQueryFeatureState () pour déterminer si la fonctionnalité demandée est déjà installée, car le programme d’installation peut parfois indiquer que la fonctionnalité est complètement installée lorsque le thread de travail copie encore les fichiers.

Heureusement, il existe une solution de contournement facile pour cela. CMsiUtil vérifie si une fonctionnalité est en cours d’installation par le thread de travail avant d’appeler des fonctions telles que MsiQueryFeatureState () ou MsiUseFeature () pour demander l’état d’installation de la fonctionnalité en question. N’oubliez pas que cette limitation peut également devenir un problème ailleurs.

La mise à jour corrective peut affecter le bon fonctionnement de l’installation à la demande sur l’ordinateur de l’utilisateur final. L’application d’un correctif qui contient uniquement des données modifiées par rapport à la version précédente peut nécessiter l’installation de la version précédente du fichier mis à jour pour appliquer le delta. Dans ce cas, le correctif doit demander que le programme d’installation a affecté les fonctionnalités publiées avant d’appliquer le correctif au jeu.

L’exemple est installé en lançant InstallOnDemand.msi, car il suppose que le Windows Installer est présent sur l’ordinateur. Si le programme d’installation est absent, les fichiers. msi ne sont pas reconnus et leur lancement ne fonctionnera pas. Pour surmonter ce problème, une application doit utiliser un programme d’installation pour effectuer la tâche. Ce programme doit d’abord vérifier si le programme d’installation est présent et, le cas échéant, sa version. Si la version ne répond pas aux exigences de l’application, le programme d’installation doit installer le Windows Installer, puis lancer le fichier. msi. Ce processus est connu sous le nom d’amorçage. En général, les applications nomment leur programme d’installation d’amorçage Setup.exe. L’exemple ne gère pas l’amorçage. Toutefois, vous trouverez des détails complets sur l’amorçage dans la Windows Installer.

Les développeurs doivent également être attentifs à la taille de chaque fonctionnalité dans leurs jeux. Lorsque vous annulez une installation en cours, le programme d’installation restaure l’ordinateur à l’état antérieur à l’installation. Cela signifie que l’installation de la fonctionnalité est complètement annulée et qu’il n’y a pas d’installation de fonctionnalité partielle. Une grande fonctionnalité nécessite plus de temps pour l’installation, ce qui augmente la probabilité que l’installation soit interrompue et annulée, ou que l’installation interfère avec l’application principale. Par exemple, vous pouvez activer l’installation passive lorsque l’utilisateur ouvre le menu du jeu au milieu du jeu. Si une fonctionnalité est installée et que l’utilisateur revient à jouer, le jeu peut effectuer l’une des deux opérations suivantes : elle peut permettre à l’installation passive de se terminer, ou elle peut annuler l’installation passive. Une grande fonctionnalité peut s’adapter mal à l’un ou l’autre des modèles. Si le jeu permet d’effectuer l’installation de grande taille, l’installation peut nuire aux performances de rendu du jeu pendant une longue période. À l’inverse, si le jeu annule l’installation, l’utilisateur doit rester dans le menu pendant un certain temps avant de retourner au jeu. Les développeurs doivent trouver une taille de fonctionnalité équilibrée qui fonctionne mieux pour leurs jeux individuels.