The Cube Engine is a game engine made by Wouter van Oortmerssen for the game Cube. This engine was reused for other games.
Description
editIt's a 3D engine, similar, by some of its aspects, to the Doom one. In both, there can't be, in theory, a place over an other. This limitation can be bypassed at using entities called mapmodels (in Doom mods, equivalent of mapmodels was also used to bypass this limitation) but they tend to be incorrectly handled by the weapons.
Most of the games using this engine (probably all) include an ingame map editor, allowing to edit any already existing maps or create new ones. These maps can immediately be played because they aren't compiled. These maps mainly consist in an array of of square zones, called cubes, that have a predefined list of properties (limiting to eight the possible orientations of any wall). Each cube is internally represented by a structure whose size depend on the game (14 bytes in Cube and 16 bytes in AssaultCube). the maps also contain entities
The number of available entity types, that vary depending on the game, is usally between fifteen an twenty but only three of them are common to all games using this engine : the mapmodels (which are mainly used to decorate the map but not only), the playerstart and the lights (especially before the introduction of the ambient light).
For characters and map models, 3D models are used. Si cube ne supporte, pour cela, que le format md2, d'autres jeu utilisant le même moteur supportent également d'autres format, comme le format md3, qui est supporté par AssaultCube.
Development
editThe development of Cube (and its engine) started in late 2000. In 2008, in a thread about the origins of Cube, Aardappel uploaded the oldest version of Cube he managed to retrieve, dated 2001-05-26
Cube was released late 2001 then became open source the next year and its development a continued until 2005, when its developpers chose to freeze this development to focus on the ones of Sauerbraten, released the previous year. Le moteur du jeu, quant à lui, a continué à être développé par des tiers.
Files
editEach map of any game using this engine correspond to one or several files. Actually, only one of these files is required. The others are optional.
The cgz file
editThis file is the sole required one. Without this one, the map isn't. It's a compressed file.
It's also the sole one the extension can vary, even if, most time, it's .cgz. In the first versions of Cube, it was .cube.gz but that was changed due to accidental uncompressions. In the game Newcube, it's .ncm.
Its encoding, once uncompressed, is the following one :
The file is divided into three part : the header, the entities list and the geometry. The version 10 of the AssaultCube Maps add a fourth part, the header extras, between the header and entities.
L'entête est ainsi constitué :
name | type | size | short description | notes |
---|---|---|---|---|
head | char [4] | 4 bytes | magic number | In Cube, it's CUBE but, depending on the game, other values can be found, such as ACMP, ACRM or NC03. |
version | int | bytes | version number | Version number of the format. Unlike what is often believed, it isn't always enough to determine encoding details (that actually depend on the couple magic number+version number). It's the cause of cause of some glitches, such as the one that happens when a pCube map is loaded with AssaultCube.
(pCube, unlike AssaultCube, is a Cube mod. pCube maps and early AssaultCube maps both have 6 as as versions number (but not the same magic number). When AssaultCube check the magic number, the map is judged valid if it's CUBE or ACMP but, later, when entities determine from what game the map is, only the version number is used) |
headersize | int | 4 bytes | header size | Usually filled with the result of the formula sizeof(header). Before the version 1.3 of AssaultCube, it merely was a remain of something planned in early development then abandoned. In that planned version, the entity list was part of the header and variable was required to determine both the number of entities and the offset of the last parts of the header. This was changed before the earliest beta. This value wasn't even checked on map loading.
In the version 1.3 of AssaultCube, that introduce the version 10 of the AssaultCube map format, this value is checked. This is required by this version of the map format. In this version, this value contain is the size of the whole header, including the header extras, and allow to determine both the amount of extra data and the offset of the next part. |
sfactor | int | 4 bytes | map size | can vary from 6 to, depending on the game, 11 or 12. the map is a square the size, in cubes, is two power this number. This, however, include a two cubes large border that always is solid and can't be modified because cubes of this border can't be selected by the map editor. Any map of size 6 is 64x64 cubes large but it's editable part only 60x60 cubes large.
The size 0=16b 1=64b 2=256b 3=1kb 4=4kb 5=16kb 6=64kb 7=256kb 8=1mb 9=4mb 10=16mb 11=64mo 12=256mo 13=1go 14=4go 15=16go 16=64go 0=14b 1=56b 2=224b 3=896b 4=3,5kb 5=14kb |
numents | int | 4 bytes | number of entities | the maximum always is 65536. If, when saved, a map contains more entities, an error message appears and only the 65536 first listed entities are saved. |
maptitle | char [128] | 128 bytes | title of the map | Full title of the map, often include the author pseudonym. Modifiable with the command mapmsg, keep it at its default value usually is seen as amateurism. |
texlists | uchar [3][256] | 768 bytes | textures indices | Each of these three indices contain exactly one occurrence of each of the 256 different possible bytes, usually in the disorder. They are used by the map editor, and define the order of the textures on texturing geometry. when a texture is set for a kind of surface (floor, wall or ceiling), the associated texture slot is moved to the top in the associated index. the first index is associated to the floor, the second is shared by the two kinds of walls and the third is associated to the the ceiling. |
waterlevel | int | 4 bytes | water level | Water level in the map. Exists since the version 4 of the map format. |
watercolor | uchar [4] | 4 bytes | water color | Unlike Cube, that, to represent water surface, use a texture (with a fixed transparency, ignoring the possible alpha channel), AssautCube use an unique color (with a variable transparency). |
maprevision | int | 4 bytes | map version number | Version number of the map. This number is increased each time the map is saved. Existe depuis la version 7 du format de cartes d'AssaultCube (utilisé à partir de la version 1.1 de ce jeu). |
ambient | int | 4 bytes | ambient light | Permet d'avoir une lumière uniforme dans la carte. Existe également depuis la version 7 du format de cartes d'AssaultCube. |
flags | int | 4 bytes | Bit field | Addition of the version 10 AssaultCube map format. in this version, there only are 4 flags, corresponding to the bits number 0, 8, 9 and 10 :
This imply the content of this field will evolve in future versions. |
timestamp | int | 4 octets | Posix time | Time (and date) of the map saving selon la norme Posix. Encoded on 32 bits, this will cease to properly work in 2038. The implementation of the map saving time carte will probably be modified or removed before. C'est également un ajout de la version 10 du format de cartes d'AssaultCube. |
reserved | int [v] | variable | reserved fied | À l'origine, ce champ faisait 64 octets (16 int) et était prévu pour de futures extensions. Finalement, dans Cube, il n'y aura qu'une extension de ce type : la hauteur de l'eau, ajoutée lors de l'implémentation de l'eau. Dans AssaultCube, il une extension de ce type dès la version 6 (la couleur de l'eau), puis deux autres dès la version 7 (numéro de révision de la carte et lumière ambiante) et la version 10 en ajoute encore deux autres (un groupe de drapeaux et l'heure de sauvegarde). Chacune de ces extensions occupe 4 octets et réduit d'autant la taille de ce champ. Le nombre remplacé ci-contre par un v peut donc, selon la version du format, être 16, 15, 14, 12 ou 10.
Afin d'éviter des problèmes de compatibilité avec des version futures, il convient de laisser à zéro (valeur NUL) tout ces octets non utilisés. |
mediareg | char [128] | 128 bytes | required data packs list | Specific to the versions 7 et 8 du format de cartes d'AssaultCube (versions 1.1.x du jeu). In the versions 1.1.x of AssaultCube, le jeu checked during map saving if certain data used came from data packs and, if so, the names of the used packs were written in this field, separated by commas. In this case, on map loading, a message appeared, saying had to be installed to correctly display, but without check were or not installed. Since AssaultCube 1.2, this mechanism has been abandoned in favor of automatic downloading, on map loading, of all available missing data, and this field is taken in account only due to the offset difference it induce (it isn't longer read). |
The Header extras are data block
the next part is the entity list. Each entity of the map correspond à une entrée de cette liste.
If they represent quite varied things, all of the entities have, for a same version of the format, the same structure and, so, the same size, 16 bytes in the version 10 of the AssaultCube map format, 12 bytes in the other cases.
Each entity is structured this way :
name | type | size | short description | notes |
---|---|---|---|---|
x | short | 2 bytes | coordonnée x | west - east |
y | short | 2 bytes | coordonnée y | north - south |
z | short | 2 bytes | coordonnée z | Is only used to determine the height of the particles effect that represents the entity in edit mode. This value doesn't affect the render or the way to work de of the entity (beside in the case of the entity fire, that only exists in Newcube). |
attr1 | short | 2 bytes | attribut n°1 | C'est le seul attribute codé sur deux octets (beside in the version 10 of the d'AssaultCube map format). |
type | uchar | 1 byte | entity type | The number associated to any available entity type depend on the couple magic number/version number of the format. This number can't be 0, since it's a special value used by the map editor. |
attr2 | uchar | 1 byte | attribut n°2 | Entier non signé (de 0 à 255). |
attr3 | uchar | 1 byte | attribut n°3 | Entier non signé (de 0 à 255). |
attr4 | uchar | 1 byte | attribut n°4 | Entier non signé (de 0 à 255). |
attr5 | short | 2 bytes | attribut n°5 | Spécifique à la version 10 du format d'AssaultCube. Peut prendre les mêmes valeurs que l'attribut n°1 (entiers signés de -32768 à 32767). |
attr6 | char | 1 bite | attribut n°6 | Spécifique à la version 10 du format d'AssaultCube. Seul attribut de type char (entier signé de -128 à 127). |
attr7 | uchar | 1 byte | attribut n°7 | Spécifique à la version 10 du format d'AssaultCube. Entier non signé( de 0 à 255). |
La troisième et dernière partie, la géométrie, consiste en une liste d'entées de longueur variable. La longueur de chacune de ces entrées dépend de son premier octet, pour lequel il peut y avoir huit valeurs différentes possibles : les numéros des six types de cubes (de 0 à 5) du jeu et deux valeurs spéciales (254 et 255).
Les six types de cubes sont les suivantes :
- SOLID (0)
- "solid" zone, impenetrable and without ground nor ceiling. most ground to ceiling walls are of this type.
- CORNER (1)
- wall (as well ground to ceiling or not) at 45° from the orientation or the cubes borders.
- FHF (2)
- Heightfielded floor, the ground can be non flat or have an height a cube of an other type can't have.
- CHF (3)
- Heightfielded ceiling, same but for the ceiling.
- SPACE (4)
- Normal cube.
- SEMISOLID (5)
- Special type, generated by the mipmapping.
the cubes of type solid (0) are described with three bytes entries :
- type (ici 0)
- texture (valeur wtex, qui, avec les autres types de cubes, correspond à la texture du mur inférieur)
- valeur delta (pour d'éventuels cubes voisins heightfieldés)
Les autres cubes sont tous décrits avec des entrées ayant la même structure de neuf octets :
- type (from 1 to 5)
- ground height (from -128 to 126)
- ceiling height (from -127 to 127)
- lower wall texture
- ground texture
- ceiling texture
- delta value
- upper wall texture
- tag
Les deux valeurs spéciales sont :
- same beside for light (254)
- abandonned since the version 3 of the map format de cartes but still supported by the map loading algorithm. A cube corresponding to an entry of this type a les mêmes particularités que le précédent, sauf pour ce qui est de la lumière.
- same (255)
- Constitue un deuxième niveau de compression. Ce type d'entrées correspond à une série de cubes identiques. C'est le seul cas où une entrée peut correspondre à plusieurs cubes. Les cubes correspondant à une entrée de ce type ont les mêmes particularités que celui de la précédente entrée d'un autre type.
La première de ces deux valeurs correspond à des entrées de trois octets :
- type (ici 254)
- intensité de la nouvelle lumière
- un octet inutilisé (rôle d'origine inconnu; totalement inutilisé aujourd'hui)
L'autre correspond à des entrées de deux octets :
- type (ici 255)
- number of cubes (de 1 à 255)
Les autres fichiers
editCes fichiers, tous optionnels, ne diffèrent du fichier cgz que par leur extension. À l'exception du ficher cfg, qui est supporté par tous les jeux utilisant ce moteur, et du fichier texte, qui n'est aucunement utilisé par le jeu, ces fichiers ne sont supportés que par certains des jeux utilisant ce moteur.
Ces fichiers se trouvent dans le même dossier que le fichier cgz, à l'exception du fichier wpt et du fichier de preview.
- Le fichier cfg
- Le contenu de ce fichier texte est, techniquement, un script en CubeScript qui est exécuté lors du chargement de la carte. Ce fichier n'est pas créé par le jeu. Il doit être créé séparément avec un éditeur de texte. Si, dans l'absolu, il est optionnel, il est nécessaire pour changer certains paramètre de la carte ou y inclure dans la carte des textures ou des mapmodels non mentionnés dans le fichier default_map_settings.cfg (dont l'emplacement varie selon le jeu), qui est toujours exécuté juste avant ce fichier.
- Ce fichier peut également comporter, en commentaires, des informations relatives à la carte, comme les droits d'auteur. Contrairement à ce qui est souvent cru, mettre ces informations dans ce fichier n'était une chose courante avec les cartes de Cube (ce n'est le cas d'aucune carte officielle de Cube), elles étaient alors plutôt mises dans un fichier séparé, généralement au format txt. Le choix de mettre ces données dans le fichier cfg à la place semble être une conséquence de l'ajout, dans AssaultCube, d'un système de téléchargement des cartes, qui ne télécharge que le fichier cgz et l'éventuel fichier cfg.
- De plus, afin d'empêcher l'exécution de scripts potentiellement malveillants, AssaultCube (et les jeux basés sur ce jeu) n’exécute que certaines commandes de ces fichiers. Les autres, au lieu de s'exécuter, causent l'affichage d'un message d'erreur.
- Le ficher texte (ou fichier txt)
- Ce fichier, qui n'est aucunement utilisé par le jeu, est parfois sans extension mais, le plus souvent, il a .txt pour extension. Son contenu est expliqué ci-dessus, dans la section sur le fichier cfg.
- the wpt file
- Specific to games using bots. Contain the waypoints used by AI of bots. The AI of the monsters, very different doesn't use waypoints.
- Le fichier de sauvegarde (ou fichier bak)
- Sauvegarde de précédentes versions du fichier cgz. Ce fichier a une double extension. La première consiste en un underscore suivi d'une série de chiffres donnée par l'horloge du système et la seconde est .bak. Il peut donc y avoir plusieurs fichiers bak pour une même cartes.
- Le fichier de preview
- spécifique à AssaultCube (et aux jeux basés sur ce AssaultCube). C'est l'image qui apparait à côté du menu dans les menus listant des cartes. Il s'agit généralement d'une image au format jgeg (ce qui est le cas pour toutes les cartes officielles d'AssaultCube) mais il peut également d'une image au format png dont l'extension a été changée. L'extension du nom de ce fichier est toujours .jpg.
Performances
editLe Cube Engine a un rendu généralement fluide. Si le nombre de frames par seconde (FPS) peut descendre très bas (plus ce nombres est élevé, plus le jeu est fluide) dans certains cas, cela reste moins fréquent qu'avec le Cube 2 Engine (moteur de Sauerbraten).