Skip to content
Docs

Models, textures and sounds

Version 1.2 of the contract: 3D models in .glb, image textures and recorded sounds in a game, how they are used from the scene and from the script, their limits and the credits.

DescribesFormat 1, API 1.2 For those who write code

On this page

Since version 1.2 of the contract a game can carry 3D models with mesh, materials, textures, skeleton and animation clips, image textures for the pieces and recorded sounds. Everything is additive: a game that does not use them stays the same.

Where each file goes#

Inside the game folder
modelos/<id>.glb         the model
modelos/<id>.json        optional: how it collides
texturas/<id>.png        loose images (png, jpg or webp)
sonidos/<id>.wav         recorded sounds (wav or mp3)
creditos.json            author, license and origin of each one

The <id> uses lowercase letters, numbers and hyphens, up to 48 characters, like sprites: robot-azul. greengames empaquetar puts everything in the .ggx.

The model format#

The only format that goes into a game is a .glb (binary glTF 2.0) that meets a strict subset. The workshop and the importer write it, and greengames validar checks it.

  • Everything goes inside the file: a single buffer, with no uri, with the images embedded. Nothing points outside.
  • Y is up and the front faces +Z. One unit of the file is one world unit: the avatar is 0.8 wide and 1.8 tall.
  • Accepted: up to 256 nodes, 32 triangle primitives and 16 materials; up to 8 PNG, JPEG or WebP images of up to 1024 pixels per side; up to 4 skeletons of 64 bones; up to 32 clips of up to 30 seconds, named with lowercase letters, numbers and hyphens.
  • Extensions: only KHR_materials_unlit, KHR_materials_emissive_strength, KHR_mesh_quantization and EXT_texture_webp.
  • Rejected: cameras, morph targets, sparse accessors, the extras key and any other extension, mesh compression included. There is no code in a model.
  • Size: up to 2 MB per file and 20,000 triangles per model.

Codes GB700 to GB715 of the validator say what fails and how to fix it.

A model in the scene#

escenas/principal.json (one piece)
{ "id": "guardia", "forma": "modelo", "modelo": "robot", "animacion": "caminar",
  "posicion": [4, 0.9, 0], "rotacion": [0, 90, 0], "tamano": [1.1, 1.8, 0.6], "material": "blanco" }
  • modelo is the id of the modelos/<id>.glb file.
  • tamano is the box it takes up: the model is stretched to fill it, and posicion is the center of that box, as with every piece. To avoid working out the natural size, create the piece from the script with mundo.crearModelo.
  • animacion is the clip played in a loop from the start. Without it, the model stays at rest.
  • material is required as in every piece, but it is not drawn: the model brings its materials. opacidad and visible do apply.
  • fisica, solida, movimiento, grupo, etiquetas and the touch events work as in any piece.

How it collides#

Never against the triangles. Each model collides as its box (by default), as an upright capsule, as a convex hull of 4 to 32 points or not at all, according to modelos/<id>.json:

modelos/robot.json
{ "colision": { "tipo": "capsula" } }

The types are caja, capsula, envolvente (with puntos: x, y, z in a row, inside the model's box) and ninguna.

The animation does not change the game#

The animation is only drawing: it does not move the piece or change how it collides. The only thing about a clip that the logic can use is its end, pieza.alTerminarClip, and that moment comes from the clip's length and the match clock: it is the same frame on every computer. That is why a game with models is still deterministic.

Characters with a model#

The player and the actors can be drawn with a model:

  • In the scene: "avatar": { "modelo": "robot" }.
  • In an actor: apariencia: { modelo: 'robot' }.
  • From the script: jugador.apariencia = { modelo: 'robot' }.

The model is drawn at the avatar's height (1.8), with its feet on the ground, and only uses its clips quieto, caminar, saltar and caer; a missing one is replaced by the closest. The character's collision does not change: it is still the avatar's.

From the script#

ts
const robot = mundo.crearModelo('robot', { id: 'r1', posicion: [0, 0.9, 5], escala: 1 });   // piece at natural size
robot.clips;                                    // ['quieto', 'caminar', 'saludar']
robot.reproducir('saludar', { repetir: false, mezcla: 0.2, velocidad: 1 });   // from the start
robot.alTerminarClip((clip) => robot.reproducir('quieto'));                    // only clips that do not repeat
robot.animacion;                                // 'saludar' (null at rest); assigning it plays it in a loop
robot.pararAnimacion(0.3);                      // back to rest, blending for 0.3 s
mundo.modelo('robot');                          // { id, tamano, clips: [{ nombre, duracion }], triangulos }
mundo.modelos();                                // ids of the game's models

The signatures are in the reference: mundo and sonido.

Textures#

An image in texturas/ (PNG, JPEG or WebP, up to 1024 pixels per side and 1 MB) is used in two ways:

  • In a piece's material, repeated: "material": { "color": "blanco", "textura": "ladrillo", "repetir": [2, 2] }.
  • As a flat image, with its transparency: { "forma": "lamina", "textura": "cartel", "tamano": [2, 1, 0.2] }. It accepts espejo and mirarCamara, like a sprite.

A model's textures go inside its .glb. The cube terrain does not use textures: its blocks carry flat colors.

Recorded sounds#

sonido.muestra('campana', { volumen: 0.8, tono: 1.2, para: jugador }) plays sonidos/campana.wav (or .mp3). A sound weighs up to 1 MB and counts toward the sounds-per-second limit, like the synthesized ones.

Credits#

creditos.json is a list with one entry per model, texture or sound:

creditos.json
[{ "recurso": "modelos/robot", "titulo": "robot.glb", "autor": "Ana", "licencia": "CC-BY-4.0",
   "origen": "Kit de plataformas", "cambios": "Convertido al formato del juego." }]

autor and licencia are required. What you made yourself is recorded with "licencia": "propia". The validator warns (GB742) about assets without a credit. The credits travel inside the .ggx; the game does not show them on screen yet.

Limits#

WhatUp to
Models per game, and size of a .glb64, of 2 MB
Triangles per model and per scene (adding up every piece with a model)20,000 and 150,000
Pieces with shape modelo alive at once300
Loose textures per game64, of 1 MB and 1024 pixels per side
Recorded sounds per game32, of 1 MB
Models, textures and sounds of a game, in total12 MB
.ggx file and uncompressed package5 MB and 20 MB, as always

Binaries travel in base64 inside the .ggx: they take a third more. All the limits are in Limits in force.

From the terminal#

greengames importar converts files from other tools to this format:

sh
greengames importar heroe.fbx --juego games/mi-juego --alto 1.8 --colision capsula --autor "Ana" --licencia CC-BY-4.0

The options are in Command-line tool.

Next#