Créer un cerveau
Un .oabrain qui joue un siège ordinateur : le dossier, chaque clé du manifeste, les étiquettes, les niveaux, la vue complète, où le script tourne, les budgets, et ce qui arrive quand il s'arrête.
Ce chapitre résume docs/brains/oabrain-standard.md, docs/brains/authoring.md et docs/playing-with-brains.md. Ces documents sont le texte normatif.
Ce qu'est un cerveau
Le joueur ordinateur du moteur reste le choix par défaut et reste dans le moteur. Un cerveau joue un siège ordinateur, et seulement un siège qu'un joueur a réglé sur lui. Un identifiant de cerveau vide est ce joueur ordinateur intégré. Un siège sans cerveau, un cerveau qui ne convient pas, et un cerveau qui s'arrête sont tous joués par ce même joueur. Classic est écrit en Lua et joue comme ce joueur. C'est la documentation de ce joueur, pas un remplacement.
Seule la machine qui fait siéger le joueur ordinateur exécute le script, donc les autres joueurs n'ont rien à installer. Leurs machines reflètent les unités du siège. Un enregistrement rejoué n'exécute pas le script. Un cerveau est du source Lua et des données. Il n'a ni code natif, ni fichier, ni réseau, ni horloge. La vue complète est un drapeau du manifeste. Un cerveau peut le régler, peut jouer avec lui dans une partie en réseau, et le siège montre le drapeau.
Le paquet
Un cerveau est un fichier .oabrain, ou le dossier dans lequel ce fichier se décompresse. Le manifeste est le YAML strict qu'utilise un profil de mod : un document, une table de premier niveau, pas d'ancres et pas de scalaires de bloc. Le sommet du paquet porte oabrain.yaml. À côté, un fichier est l'un de ceux-ci. Un fichier hors de cette liste est refusé.
my-brain.oabrainle fichier qu'un joueur obtient├─ oabrain.yamlrequis le manifeste, au plus 256 Kio├─ brain.luale script d'entrée. Le nom par défaut est brain.lua. entry en nomme un autre, et ce fichier doit être dans le paquet├─ lua/d'autres sources Lua. require ne lit que ces fichiers. Chaque partie est faite de lettres minuscules, de chiffres et de _├─ nets/un réseau que le manifeste nomme, nets/ et un radical qui finit par .oann├─ data/une table de données, à un dossier de profondeur : .csv, .tdf, .json ou .txt├─ icon.pngl'image, seulement quand icon la nomme. Sans cette clé, le fichier est hors liste├─ README.mdune note au sommet. Le jeu ne la charge pas└─ LICENSEla licence au sommet. Le nom licence, et un readme dans un sous-dossier, sont hors listeLa comparaison ignore la casse des lettres ASCII, sauf là où le standard dit que les octets doivent correspondre. brain.lua est hors liste quand entry nomme un autre fichier. Un fichier Lua fait au plus 1 Mio. L'icône est un PNG carré, chaque côté au plus 256 pixels, au plus 256 Kio. OA installe un cerveau dans Brains/ et l'identifiant du manifeste.
Le manifeste
Le lecteur rassemble chaque règle cassée et laisse le manifeste inchangé quand une règle est cassée. Une clé que le standard ne liste pas est refusée. Une clé de profil appartient à un mod. Une clé de mutateur est refusée comme clé de mutateur. Mettez une version entre guillemets, car un 1.0 nu est un nombre, et mettez une étoile entre guillemets, car une étoile nue est un alias YAML.
| Clé | Requis | Rôle |
|---|---|---|
oabrain | oui | Le format. L'entier 1. 1.0 et un 1 entre guillemets sont refusés. |
id | oui | Kebab-case en minuscules, de 1 à 64 octets. Pas de tiret en tête, en fin ou doublé. Le nom du dossier sous Brains/. |
name | oui | De 1 à 64 octets, aucun caractère de contrôle. Le nom que les joueurs voient. |
version | oui | Entre guillemets, une à trois parties, une version de mutateur, comme « 2.0 ». Un nombre nu est refusé. 2, 2.0 et 2.0.0 se comparent comme égaux. |
author | oui | Une table. name est requis, de 1 à 128 octets. email est facultatif. |
description | oui | Requis, de 1 à 2 000 octets. Un saut de ligne est permis. Tout autre caractère de contrôle est refusé. La première ligne, coupée à 200 octets, est le résumé. |
homepage | non | Une adresse http ou https. |
icon | non | Seulement icon.png, l'image au sommet du paquet. Tout le reste est refusé. |
tags | oui | De 1 à 4 des neuf étiquettes ci-dessous, aucune répétée. |
works-with | oui | De 1 à 32 conditions, aucun identifiant en double. Une étoile veut dire n'importe quel mod et le jeu de base, et elle est alors la seule entrée. ta-3.1c veut dire le jeu de base sans mod. Tout autre identifiant est un mod, avec une plage de version facultative. |
requires | non | Seulement engine et expansions. engine est une plage, entre guillemets quand elle commence par un signe supérieur. expansions compte de 1 à 16 identifiants de bundle. Un cerveau ne peut pas exiger un mutateur. |
levels | oui | De 1 à 6 niveaux. Chaque table est exactement id, name et difficulty. |
fullAwareness | non | true ou false. L'absence veut dire false. Un true entre guillemets est refusé. |
networks | non | De 1 à 16, chacun exactement id, file et sha256. file est nets/ et un radical qui finit par .oann. sha256 est 64 chiffres hexadécimaux en minuscules entre guillemets. |
options | non | Au plus 16, les règles d'options du mutateur. Une bascule vaut true ou false, un nombre est un nombre, et un choix est son texte. me.options les lit. |
strings | non | Au plus 16 langues. Une langue peut contenir name, description, options, labels et levels. |
entry | non | Un fichier Lua au sommet du paquet, nommé avec des lettres minuscules, des chiffres et _. L'absence veut dire brain.lua. |
Les neuf étiquettes
Une étiquette est l'une de ces neuf, comparée octet pour octet. Plus de quatre, quand la règle d'étiquettes partagée a déjà été passée, est un problème à part. Une étiquette qui n'est pas l'une des neuf est refusée.
| Clé |
|---|
classic |
economy |
rush |
turtle |
air |
naval |
learned |
teaching |
experimental |
Niveaux et difficulté
levels est une liste de 1 à 6 tables. Chacune est exactement id, name et difficulty, tous requis. id est un kebab-case en minuscules de 1 à 32 octets, et aucun id n'est répété. name fait de 1 à 64 octets, sans caractère de contrôle. difficulty est easy, medium ou hard, octet pour octet.
Ces trois noms sont les valeurs 0, 1 et 2. Un siège qui choisit le niveau utilise cette valeur comme ses règles de revenu, la même difficulté que le jeu utilise déjà.
Vue complète
fullAwareness est true ou false. L'absence veut dire false. Un cerveau qui a le drapeau voit des unités qu'un siège dans le brouillard ne verrait pas, comme le fait le joueur ordinateur intégré, et ses vérifications de site n'ont pas besoin d'un joueur qui place. Le drapeau est permis dans une partie en réseau. La Bibliothèque affiche Voit chaque unité sur la carte, comme le joueur ordinateur de Total Annihilation. Le drapeau est propre au manifeste. L'identifiant du paquet ne l'accorde pas, et il ne fait pas partie de ce qui n'est donné qu'à Classic.
Où un cerveau tourne
Seule la machine qui fait siéger le joueur ordinateur a besoin du paquet, et seule cette machine exécute le script. Un siège est un joueur ordinateur de cette machine. Un siège humain est refusé. game.mode est skirmish, campaign ou network.
| Situation | Ce qui tourne |
|---|---|
| Escarmouche | Chaque siège ordinateur que cette machine joue, quand un joueur y a mis un cerveau. Un identifiant vide est le joueur ordinateur intégré. |
| Mission de campagne | Le siège de campagne suit le cerveau par défaut que le joueur a réglé. Une mission n'ignore pas ce choix par défaut. |
| Partie en réseau | La machine qui possède le siège ordinateur fait tourner le cerveau, vue complète comprise. Les autres machines ne le font pas. |
| Partie sauvegardée chargée plus tard | La sauvegarde nomme chaque siège. Le standard dit ce qui arrive quand le paquet manque ou que la version diffère. |
| Enregistrement rejoué | L'enregistrement conserve le texte des cerveaux. La relecture applique les paquets enregistrés. Elle ne fait siéger aucun cerveau et n'appelle pas ses hooks. |
| Deathmatch ou tournoi | Le lancement ne fait siéger aucun joueur ordinateur. |
Le cerveau qu'un siège joue n'est pas une entrée de l'empreinte de la simulation. Deux parties qui ne diffèrent que par le cerveau mis en siège gardent la même empreinte d'état de la partie. Les valeurs des règles ai.* du mod font partie du profil de mod que cette empreinte couvre, donc elles parviennent encore à chaque machine.
Les budgets d'exécution
Un cerveau tourne en Lua dans un seul bac à sable. Deux cerveaux ne partagent ni modules, ni globales, ni budgets. Le script n'a ni fichier, ni horloge, ni environnement, ni processus, ni réseau. Chaque fragment est chargé comme du texte. pcall et xpcall ne peuvent pas garder en vie une phase épuisée. Un tour est un appel pris sur la banque, au point de contrôleur du siège, après le balayage des unités. Les ordres qu'un hook donne prennent effet au tick suivant.
| Budget | Valeur |
|---|---|
| Instructions dans load, fits, start, save et report | 50,000,000 |
| Instructions qu'un tick ajoute | 2,000,000 |
| Ticks que la banque peut tenir, tick courant compris | 30, donc le solde s'ouvre à 60,000,000 |
| Mémoire Lua | 64 Mio (67,108,864 octets). Il n'est pas remis à zéro entre les phases. |
| Mémoire réseau | 64 Mio, séparé du plafond Lua |
| Temps réel, une phase qui n'est pas un tour, en millisecondes | 10,000 |
| Temps réel, un tour, en millisecondes | 250 |
| Une chaîne, en octets | 65,536 |
Quand un cerveau échoue
Un cerveau s'arrête pour une erreur dans un hook ou un minuteur, une allocation d'instructions épuisée, le filet de temps réel, le plafond de mémoire Lua, une chaîne de plus de 65 536 octets, ou un chargement que le siège refuse. Un tour en échec ferme le bac à sable et retire les hooks avant le retour de ce tour. Le tour en échec compte tout de même comme joué. Le tick d'ordres suivant n'a pas de hooks, donc le joueur ordinateur intégré le prend. Un cerveau qui est refusé, qui ne démarre pas, ou qui ne convient pas n'a jamais de hooks, donc ce joueur joue dès le début. L'avis utilise le nom du manifeste et la raison, coupée à 160 octets :
- `{brain} stopped ({reason}); the engine plays this seat on`
- `{brain} could not start ({reason}); the engine plays this seat`
- `{brain} does not fit this game ({reason}); the engine plays this seat`
Quand le siège n'a pas de raison propre, la raison est the brain could not be seated. Un joueur vaincu n'est simplement plus appelé. Le bac à sable se ferme avec la partie.