Skip to content
Docs

Open world

The game type made of generated cubes, with its biome table, how blocks are broken and placed, what gets saved and how to start from the template.

DescribesFormat 1, API 1.1 For those who write code

On this page

An open-world game is not built piece by piece: the engine generates a world of cubes from a seed and a biome table, and the script sets the rules. It is version 1.1 of the contract.

Start from the template#

sh
greengames crear mi-valle --tipo mundo-abierto --nombre "Mi valle"
greengames validar mi-valle
greengames probar mi-valle
Output of probar (last line)
mi-valle: prueba aprobada (6 de 6 corridas, .ggx de 8.4 KB)

The template is a complete, short game: gather wood and then place those blocks. Its files:

FileWhat it has
escenas/principal.jsonThe terreno: 31 blocks, 9 biomes and the generator settings. Also the objetivo piece, the marker that guides the player.
scripts/principal.tsThe rules: breaking, placing, the hotbar, the goal and saving. It generates nothing.
pruebas/bot.jsonThe bot script: it goes to the marker, looks at it and holds the button. It knows no coordinates.

To make a world of your own you change the table in the scene, without touching the script.

From the editor#

In editor 0.4.0 the open world is one more kind of game. In New game there are two ways, depending on what you choose under How it is programmed:

  • Rules or code: the Open world kind with the Open world example template, which comes with code. See Game types.
  • Blocks: the Crystals and cubes example. See Blocks.

The project is tested with the bot and exported to .ggx like any other.

The terrain in the scene#

It goes in terreno, inside the scene file. A block measures 1 x 1 x 1 and its coordinates are integers. The world is 64 blocks tall and reaches limite on X and on Z; beyond that it is sea. It is generated in chunks of 16 x 16 blocks, as someone gets close.

PropertyNotes
semillaFixed seed: the same world in every match. Without it, or with 0, the world comes from the seed of the match: a different one each time.
nivelDelMarHeight of the water. 22 by default.
distanciaDraw distance the game asks for, in chunks: from 2 to 12. 6 by default. The game player shortens it if the computer cannot keep up and lengthens it again.
limiteHow far the world reaches: from 64 to 2000.
subirBloquesCharacters step up one block on their own, without jumping. true by default.
bloquesThe block types, by id. Up to 200. aire is reserved.
biomasThe biome table. Up to 24, and at least one land biome.
generadorGenerator settings: stone, water, caves, ores and structures. All optional.

A block carries its color and, if needed, arriba and abajo for those faces. With "liquido": true it is water: it does not flow, you float and swim in it. With "forma": "cruz" it is a plant. dureza is the seconds it takes to break it, and -1 means it cannot be broken: it is data for the script, the engine only reports it.

escenas/principal.json (fragment)
"terreno": {
  "semilla": 2026,
  "nivelDelMar": 22,
  "distancia": 6,
  "bloques": {
    "pasto":  { "color": "#8a5a34", "arriba": "#5fc234", "dureza": 0.6 },
    "tierra": { "color": "tierra", "dureza": 0.5 },
    "agua":   { "color": "#2f8fe0", "liquido": true, "dureza": -1 },
    "tronco": { "color": "madera", "etiquetas": ["madera"] },
    "flor":   { "color": "ambar", "forma": "cruz", "dureza": 0 }
  },
  "biomas": [
    { "id": "pradera", "temperatura": 0.5, "humedad": 0.4, "altura": 3, "relieve": 5, "superficie": "pasto", "subsuelo": "tierra" },
    { "id": "oceano", "zona": "mar", "superficie": "arena" },
    { "id": "playa", "zona": "costa", "superficie": "arena" }
  ]
}

The biome table#

Each row says in which climate the biome appears, how high and rugged it is, what it is made of and what grows there.

PropertyNotes
idUnique.
zona"tierra", the default: chosen by climate. "mar": what lies under the water. "costa": the strip at sea level.
temperatura, humedadIdeal climate, from 0 to 1. At each place the land biome closest to the climate there wins.
altura, relieveBlocks above the sea in the low parts, and how much the relief rises over that. Neighboring biomes blend: the border is a slope, not a step.
superficie, subsuelo, profundidad, fondoThe top block, the one below and how many layers before the stone. fondo is the surface when it lies under water.
cimaFrom that height up the surface is another block: { "desde": 40, "bloque": "nieve" }.
arbolesUp to 4: densidad, tronco, hojas, alto and copa. Without leaves it is a bare trunk, like a cactus.
plantasUp to 6: a block and its densidad, scattered on the surface.

To add a biome, copy a row, change its id and give it a climate no other one has. Always keep one with "zona": "mar" and one with "zona": "costa".

These are the nine biomes of the template, the same as in Open Valley:

BiomeTemperature and humidityHeight and reliefSurfaceWhat grows
Meadow0.5 and 0.423 and 5grassscattered trees, tall grass, flowers
Forest0.42 and 0.744 and 8grasstrees, tall grass
Desert0.9 and 0.123 and 6sandcactus, dry bushes
Snowy mountain0.14 and 0.387 and 24stone; snow from height 40pines
Tundra0.1 and 0.783 and 5snowpines
Swamp0.66 and 0.92-1 and 2.5mudtrees, reeds
Jungle0.88 and 0.784 and 9grassjungle trees, tall grass
Oceanmar zonesand
Beachcosta zonesand

Breaking and placing#

Breaking and placing are decided by the script: the engine gives the ray, changes the block and notifies. There are two actions for it, declared in controles.acciones of the manifest like the others:

ActionKeyboard and mouseGamepadTouch screen
primariaLeft click, or JRight triggerHolding a finger still on the game
secundariaRight click, or KLeft triggerA short tap on the game

The skeleton, as it is in the contract:

scripts/principal.ts
const terreno = mundo.terreno;

juego.cadaCuadro(() => {
  for (const j of jugadores.todos()) {
    const a = j.apuntaBloque(5);
    interfaz.marcarBloque(a ? a.posicion : null, {}, j);
    if (a && j.pulsa('primaria')) terreno.romper(a.posicion[0], a.posicion[1], a.posicion[2], j);
  }
});
jugadores.alAccion('secundaria', (j) => {
  const a = j.apuntaBloque(5);
  if (a) terreno.poner(a.vecino[0], a.vecino[1], a.vecino[2], 'tabla', j);
});
  • jugador.apuntaBloque gives the block being pointed at, the face touched and vecino, the cell where a new block would go.
  • terreno.romper returns the id of what was there. The template adds it to an inventory and shows it with interfaz.barraRapida.
  • terreno.poner returns false if there is a player or an actor in that cell: it does not let you wall anyone in.
  • The bottom of the world cannot be touched, nor what lies outside limite.
  • The template uses dureza so that breaking takes time: it counts the seconds with the button held and shows the progress with interfaz.marcarBloque.

Every function: The mundo service.

Saving#

The world is not saved: it is generated again from its seed. What is saved is only what differs from the generated world.

  • terreno.guardar(jugador) writes those changes to the progress of that player, together with the seed. It returns how many blocks and how many bytes it took.
  • terreno.restaurar(jugador) goes back to that world and puts the changes on top. It returns how many blocks it restored.
  • terreno.borrarGuardado(jugador) deletes them.

The template calls restaurar when the player joins and guardar when the match ends.

CapValue
Changed blocks remembered at a time60,000
Saved changes320 KB, apart from the 64 KB of progress
Cells per call to terreno.llenar4096
Hotbar slots9

On reaching the cap of changed blocks, poner and romper fail with a clear message: terreno.cambios says how many there are. Every cap: Limits.

Launcher 0.4.0 saves those changes to disk along with the rest of the game's progress: up to 384 KB per game, which are the 64 KB of progress and the 320 KB of terrain changes. So an Open Valley world you save is still there the next time you open the launcher.

How it behaves#

  • Spawn points drop to the ground. In a scene with terrain, the height of a spawn point is ignored: the player lands on the ground of that column or, if there is sea there, on the nearest land.
  • Collision. Players, actors and dynamic pieces collide with the terrain. Pieces, zones, lights and actors keep working as usual.
  • Water. Whoever enters a liquid block floats; with saltar they swim up and climb out at the shore.
  • Fog. The game player puts fog at the draw distance. The niebla of the ambience is not used in a scene with terrain.
  • The bot walks the generated world with "ruta": true: it goes around trunks and slopes, and swims if there is water.

What is missing#

  • Launcher 0.2.0 and editor 0.2.0 do not ship the cube terrain: you need version 0.3.0.
  • The editor has no biome or block editor: Details shows the biome table read-only, in the Open world category, with the label "editor: coming soon" and a button to open the project folder. You change the table in the scene file.
  • What Blocks mode does not do yet with the world of cubes is in Blocks.
  • There is no online open world.
  • Water does not flow and the light of a block does not light its neighbors.
  • There are no enemies or wildlife made for the terrain.

Next#