Quelle est la technologie qui permet de programmer dans un jeu?


27

Il existe des jeux qui permettent au joueur d'écrire / créer des scripts dans le jeu, par exemple: les ingénieurs spatiaux ou Psi .

Je veux utiliser quelque chose de similaire à l'un ou l'autre, mais j'ai eu du mal à trouver des informations donc ma question est:

Existe-t-il une branche de programmation qui couvre la capacité d'un logiciel une fois compilé à exécuter le nouveau code créé par l'utilisateur?

Par branche de programmation, je veux dire quelque chose comme PTG (génération de terrain procédural).

Pour éviter une question trop large ou basée sur une opinion , permettez-moi de déclarer clairement que je ne recherche pas de guides ou de lieux d'apprentissage, je veux le nom ou la définition (s'il en existe une) de la technologie impliquée.


22
Eh bien, probablement "Écrire des interprètes"?
MatthewRock

2
J'ai répondu récemment à une question similaire , en discutant de « machine virtuelle » comme terme pour le système qui exécute le code utilisateur, et en faisant également référence à l'article Game Programming Patterns sur le modèle Bytecode comme moyen de l'implémenter plus rapidement qu'un interprète conventionnel.
DMGregory

3
Cela s'appelle généralement "scripting". Vous trouverez de nombreux documents sur la façon d'implémenter les scripts dans un jeu, ainsi que de nombreux exemples de code source ouvert et de code réel. Dans une portée plus large, il y a tout le domaine de la programmation du compilateur (qui comprend lexing, l'analyse, la compilation, la liaison, l'interprétation ...). Dans la portée la plus large (pas nécessairement utile), cela implique à peu près n'importe quelle interaction utilisateur avec votre application - un moteur de script est vraiment juste un moyen beaucoup plus complexe de sélectionner dans un menu.
Luaan

2
Un programme Python peut héberger des scripts Python. C'est ce qu'on appelle la métaprogrammation. La plupart des langues interprétées ont cela.
user6245072

1
AFAIK dans Space Engineers, le code est du code C # compilé dans un environnement en bac à sable (le jeu est devenu open-source, vous pouvez donc vérifier comment cela fonctionne en ligne: github.com/KeenSoftwareHouse/SpaceEngineers ). Fondamentalement, le jeu est livré avec un compilateur C # et le code autorise uniquement l'accès aux fonctions API du jeu, de sorte que la portée du programme est limitée à vous uniquement. Et si vous jouez en multijoueur, alors le code ne fonctionne que sur votre machine (les autres joueurs / le serveur ne voient que les conséquences dans le jeu)
Florian Castellane

Réponses:


42

Les scripts écrits dans des langages de script / incorporés / interprétés tels que "Lua", "Lisp" ou "AngelScript" ( plus ici ) peuvent être mis à jour pendant le jeu [*] puis sont interprétés (= exécutés) à la volée.

Vous pouvez lier des éléments de ces scripts à votre codage natif compilé (C ++, etc.) afin que les scripts puissent ensuite exécuter la logique à partir de votre application. Par exemple. une commande spécifique que l'utilisateur peut mettre dans le script, ce qui déplace le personnage du jeu d'une distance donnée dans le monde du jeu.

Quelques questions liées pertinentes:


[*] soit par l'utilisateur dans le cadre du jeu, soit également par les développeurs pour une itération / un test rapide sans redémarrer l'application


14
Je serais prudent en appelant quelque chose de "langage interprété". Au mieux, c'est un terme très contestable.
wondra

1
Computercraft (minecraft mod) utilise LUA comme langage de script pour programmer des tâches dans le jeu.
Tikeb

20
Je ne comprends pas vraiment le bruit. Lisp peut être à la fois interprété et compilé. Nous ne sommes pas ici pour discuter comment classer les langues et si interpretedc'est une bonne classification; nous disons à OP qui ignore ce fait que la langue n'a pas besoin d'être compilée, mais peut être interprétée - et nous donnons quelques langues comme exemple. Lisp est-il interprété? Oui. Est-il compilé? Oui aussi! Mais cela sort du cadre. La réponse est peut-être inexacte avec le libellé, mais c'est très bien pour le but; il pousse OP dans la bonne direction, et c'est ce qui compte. Ici, prenez mon +1.
MatthewRock du

1
Eh bien, même si un langage est uniquement compilable, qu'est-ce qui vous empêche d'incorporer un IDE, un compilateur et un runtime dans votre jeu? Sauf le budget, bien sûr.
Ordous

3
@DanielJour Bien que je convienne que, théoriquement, un langage peut être distinct de son implémentation (compilé en code machine vs compilé en bytecode pour un vm), c'est toujours une hypothèse qui fait gagner du temps que C est compilé sauf indication contraire (et pouvez-vous imaginer les regards que vous obtiendriez si vous demandiez, "attendez, compilé C ou interprété C?" à chaque fois). Aux fins du PO, il doit examiner les langues qui prennent en charge l'interprétation; si elles peuvent être compilées ou non, ce n'est pas un problème, car ce n'est pas ainsi qu'il les utiliserait.
Blackhawk

12

Le langage intégré est le terme technique approprié. En pratique, les langages utilisés dans d'autres applications (comme les jeux) sont souvent appelés langages de script ou même interprétés , bien qu'ils ne doivent pas nécessairement être interprétés ou utilisés pour automatiser des tâches de routine. La recherche sur les «langages de script pour les jeux» donnerait probablement des résultats plus utiles que la recherche des «langages intégrés».


11

Vous cherchez un moyen de changer le code en quelques actions. C'est précisément ce que font les interprètes .

Jetez un oeil à Python. Vous l'exécutez et bam! Vous atterrissez en REPL ( R ead E val P rint L oop).

Vous définissez une fonction "bonjour" qui imprime "bonjour, monde". Et voila!

Notez que vous n'avez rien compilé; L'interprète a fait de la magie pour créer une fonction à la volée (pendant l'exécution) et maintenant vous pouvez l'appeler.

Il en va de même pour les jeux. Au lieu d'avoir un REPL, vous avez un jeu avec le module REPL. Le jeu démarre probablement le REPL, puis exécute tout le reste dans ce REPL, vous avez donc accès aux données et pouvez les modifier activement.

Si vous travaillez avec des langages énormes comme C ++, ils ont tendance à être moins dynamiques et probablement compilés. Vous en voulez plus facilement. Soit vous créez votre propre langage, soit vous en utilisez un existant (comme CoffeScript, Squirrel, Lua, Scheme, ...)

Ceux-ci sont souvent appelés langages de script , car vous les utilisez pour écrire des scripts qui sont construits sur le moteur de jeu développé dans un autre langage (par exemple C ++).


2

Si le langage de programmation en jeu n'a été conçu que pour le jeu, il s'agit d'un langage spécifique au domaine .

L'avantage (et l'inconvénient) des langues spécifiques au domaine est que la langue elle-même peut limiter ce que l'utilisateur peut faire (c'est-à-dire que vous pouvez interdire la connexion à Internet). Vous pouvez concevoir un langage qui rend les tâches de jeu typiques plus faciles que dans un langage général. L'inconvénient est que l'utilisateur doit apprendre une nouvelle langue.

Le simple fait d'exécuter du code utilisateur nonanitized dans un langage à usage général (comme python ou perl) à partir de votre jeu, pourrait permettre à l'utilisateur de jouer avec des choses avec lesquelles il ne devrait pas jouer. Mais cela dépend de votre jeu. Si cela ne vous dérange pas que les utilisateurs fassent des choses comme ouvrir de nouvelles fenêtres à partir de votre jeu ou tout ce qu'ils veulent, vous pouvez utiliser un langage général et exposer les liaisons à certaines fonctionnalités de votre monde de jeu.


1

Il y a deux exemples auxquels je peux penser du haut de ma tête. Les deux semblent faire exactement ce que vous demandez.

Le premier est des screeps. https://screeps.com/ Vous pouvez lire beaucoup sur la façon dont il atteint cet objectif à http://support.screeps.com/hc/en-us/articles/205960931-Server-side-architecture-overview

Le second est ComputerCraft http://www.computercraft.info/ Ils n'entrent pas dans les détails quant à la façon dont cela fonctionne mais un peu peut être vu sur leur wiki http://www.computercraft.info/wiki/Main_Page

En substance, le jeu principal exécute un interpréteur dans un thread séparé, puis permet à ce thread de manipuler le monde du jeu via des appels d'API.

Dans les deux exemples, alors que la langue est presque illimitée (seuls certains appels sont bloqués pour des raisons de sécurité), les manipulations sont limitées par les appels d'API qui peuvent être effectués.

Habituellement, très peu de travail est nécessaire pour démarrer quelque chose comme ça. Vous avez besoin

  • un gestionnaire de threads qui protège la boucle de votre jeu (ne permet pas à un thread de verrouiller la boucle ou de consommer de nombreuses ressources). Les deux exemples utilisent un limiteur basé sur le temps.
  • un interprète pour exécuter une langue. LUA est assez courant de nos jours.
  • un ensemble d'appels API qui modifient le monde du jeu. Quel plaisir est un langage de programmation si vous ne pouvez rien en faire.
  • une implémentation de la gestion des ressources. En d'autres termes, un moyen de stocker des fichiers de code et de les référencer dans le jeu.

Il n'y a pas une seule branche de programmation qui gère toutes ces préoccupations. Mais vous aurez besoin d'une base solide en multi-threading et d'une connaissance générale du fonctionnement d'un interprète.


0

L'exécutable compilé doit contenir un analyseur capable de lire le code de programme externe . Le code du programme n'a pas besoin de ressembler à C ou Python ou xyz - il peut s'agir de n'importe quel type de données descriptives qui conviennent à l'objectif en question. Par exemple suédois ou morse.

Le code du programme externe doit avoir une syntaxe , de sorte que l'analyseur le comprenne lorsqu'il le lit caractère par caractère. La syntaxe peut décrire (et numéro) peut contenir des identificateurs, des valeurs numériques, des opérateurs , etc .

L'analyseur est fixe (compilé) mais il fonctionne sur du code externe flexible.

L'exécutable compilé doit avoir une API interne pour ses fonctionnalités pertinentes. afin que l'analyseur puisse effectuer des actions. Très probablement, il doit également y avoir un accès (bidirectionnel) aux données internes de l'exécutable, ou l'analyseur doit fournir une sorte de stockage de données et d'entretien ménager.

L'analyseur peut lire le code du programme externe au démarrage de l'exécutable , ou il peut le lire (en partie) ad hoc , ou il peut le relire pour chaque trame (serait inefficace), ou le code peut même être tapé à la main et affiché sur l'analyseur au fur et à mesure qu'il se prépare (comme: "déplacer l'unité X de 5 pas vers l'avant" [entrer]).

Essentiellement, le code externe n'est pas fixe - il peut changer n'importe quelle année, jour ou minute, mais l'exécutable n'a pas besoin d'être recompilé. Seul le comportement résultant, hébergé par l'exécutable, change.

Le texte que vous lisez en ce moment est (en quelque sorte, et encore plus s'il a été prononcé) interprété parce que vous "l'exécutez" dans votre cerveau tout en le lisant, sans savoir ce que dit la prochaine phrase (ou même si elle change peut-être sournoisement à droite à présent). Contrairement à Stack Overflow (pré) compilant toute l'histoire en bytecode dans votre cerveau, qui l'exécute ensuite - et bien sûr, cela ne pourrait plus changer.

Le phénomène en cours est l'interprétation. Le script n'est que l'acte de créer une description ou d' écrire . Tout le codage informatique est un script imo - nous décrivons ce que nous voulons faire. Le mot "scripting" a une signification quelque peu inclinée, mais alors ça va. Nous savons ce que nous voulons dire.

Il n'y a absolument rien d'extraordinaire avec les langues interprétées, et ce n'est en aucun cas un terme contestable . Il en existe une multitude et certaines des plus anciennes sont interprétées plutôt que compilées. Dans un langage interprété, on pourrait par exemple taper à la main:

sock = Socket.New (AddressFamily.InterNetwork, SocketType.Stream ProtocolType.Tcp) [ENTRER]

... et partez pour une pause café de 30 ... non, 45 minutes :-). Au retour, "sock" existe et est prêt pour une utilisation ultérieure en tapant plus à la main ou en laissant l'automatisation de l'interpréteur continuer avec.


Il y a une idée fausse commune selon laquelle un langage interprété doit être lent. Ce n'est pas vrai. En fonction des différents facteurs qui rendent cette discussion trop large pour les commentaires, le langage interprété peut être d'une ampleur ou moins lent, aussi rapide ou même pour certaines opérations plus rapide que le langage de contrôle considéré comme rapide (généralement C). L'exemple avec socket fonctionnerait probablement plus ou moins comme en C, donc l'exemple est trompeur. Vous pouvez également redéfinir les fonctions compilées à l'exécution dans certains langages, et interpréter ne signifie pas simplement "exécuter une instruction à la fois".
MatthewRock

Bien sûr, un langage interprété peut également fonctionner plus rapidement - après tout, c'est le bytecode qui s'exécute, et l'exécution peut être beaucoup mieux optimisée, selon l'automatisation de l'interpréteur. De plus, certains interprètes peuvent compiler, à partir du code, des parties du code en bytecode (et les exécuter), ad hoc. L'exemple n'est qu'un exemple de la liberté, "Aller une instruction à la fois"? Eh bien, c'est une simplification excessive, peut-être ajouter "alors que le futur code est flexible".
Stormwind

Pensez au "script" plus comme un scénario de film - vous avez toujours besoin d'acteurs, et ceux-ci sont définis directement en termes de biologie et de sociologie, pas de sciences du théâtre (bien que ceux-ci soient finalement basés sur la biologie et la sociologie), parce que ces langues sont plus adapté à cet effet mais pas l'autre :)
rackandboneman
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.