PYBLOCKS / DOCUMENTACIÓN

PyBlocks Lab: bloques propios en Python

Escribí tus propios bloques en Python, cargalos en la paleta y compartilos con otros proyectos como paquetes .pbblock.

Abrir el Lab

Abrí un proyecto y apretá Ctrl+Shift+L (o usá Tools → PyBlocks Lab, el botón Lab de la barra de workspaces o Ctrl+6). Cada proyecto guarda sus módulos de Python en su propia carpeta plugins/.

PyBlocks Lab con el plugin de ejemplo de The Little Garden.
PyBlocks Lab con el plugin de ejemplo de The Little Garden.
  • La lista de arriba muestra los archivos .py de plugins/.
  • New plugin crea un módulo a partir de una plantilla que ya funciona.
  • Import .pbblock y Compile package… leen y generan paquetes de bloques.
  • Unload saca los bloques del módulo de la paleta; Save & Load (Ctrl+Enter) guarda el módulo y registra sus bloques.
  • La línea de estado, debajo del editor, te cuenta qué pasó, incluidos los errores de carga.

Los borradores se guardan solos mientras escribís, pero la paleta solo cambia cuando apretás Save & Load.

Tu primer bloque

  1. Hacé clic en New plugin y escribí un nombre con minúsculas, números y guiones bajos que empiece con una letra, por ejemplo my_blocks.
  2. El módulo nuevo ya trae un bloque de ejemplo, Spin by speed.
  3. Apretá Save & Load. La línea de estado dice cuántos bloques se cargaron.
  4. Andá al workspace Blocks, buscá el bloque en la categoría Lab y encastralo debajo de On Update.
  5. Apretá Ctrl+P: el objeto gira.
def register(api):
    api.block("spin", "Spin by speed", spin, fields=[
        {"name": "speed", "field_type": "number", "default": 90, "label": "degrees / sec"}
    ])

def spin(ctx):
    ctx.obj.rotation_degrees += ctx.number("speed", 90) * ctx.dt

Cada bloque recibe un ID estable formado por el nombre del archivo y el del bloque, por ejemplo lab_my_blocks.spin. Si renombrás el archivo o el bloque, se rompen los scripts que ya lo usan.

La API de bloques

Un módulo tiene que definir register(api) y registrar al menos un bloque con api.block(name, label, callback, fields=[...]). Los argumentos opcionales color y category valen por defecto "#a78bfa" y "Lab".

  • name: un identificador en minúsculas, único en el módulo.
  • label: el texto que muestra el bloque.
  • fields: una lista de diccionarios con name, field_type (number, text, boolean o dropdown), default, label y, para los desplegables, options.
  • callback(ctx): se ejecuta cada vez que corre el bloque.

El callback recibe ctx con ctx.obj (el objeto en ejecución: posición, rotación, variables…), ctx.session (la sesión del motor: objetos, entrada, animación, partículas), ctx.dt (los segundos del frame actual), ctx.fields (los valores de los campos del bloque) y ctx.number(name, default), que devuelve un número y da error si el valor no es válido. Por ejemplo, ctx.session.particles.emit(ctx.obj.x, ctx.obj.y, count=24) emite partículas.

Esta primera versión de la API solo crea bloques de pila. No puede agregar eventos nuevos, reporters, bloques C ni paneles del editor.

Si una recarga falla, queda registrada la última versión que funcionaba y la línea de estado muestra el error. Los errores dentro de un callback mientras corre el juego pasan por el diagnóstico normal de bloques e indican qué bloque falló. Cargar o descargar un módulo detiene el juego en curso.

Paquetes de bloques (.pbblock)

Compile package… convierte el módulo abierto en un archivo .pbblock portable. Verifica que el ID del paquete (el nombre del archivo del módulo) empiece con una minúscula y use solo minúsculas, números y guiones bajos (64 caracteres como máximo), que el código pese 512 KB o menos y que defina register(api).

my_blocks.pbblock  (a zip file)
├── manifest.json
└── plugin.py

manifest.json:
{
  "format": "pyblocks.block-package",
  "version": 1,
  "api_version": 1,
  "id": "my_blocks",
  "entrypoint": "plugin.py",
  "sha256": "<SHA-256 of plugin.py>"
}

Import .pbblock revisa el formato, la versión de la API y el checksum, y después copia plugin.py a plugins/<id>.py. Nunca ejecuta el código ni sobrescribe un módulo con el mismo ID. Leé el código importado en el editor y después apretá Save & Load para activarlo.

Código de terceros

Los plugins del Lab son Python común, con acceso total a tu computadora. No hay sandbox: los callbacks corren en el hilo del editor, y el límite de bucles que protege a los scripts de bloques no frena un bucle infinito de Python. Evitá llamadas bloqueantes, esperas largas y bucles sin límite.

El código que no se escribió en esta computadora, como un paquete importado o un plugin que vino dentro de un proyecto copiado, no se ejecuta hasta que lo confirmás. Al apretar Save & Load aparece la ventana Load third-party code? con el ID del paquete y el archivo de origen, y el SHA-256 del código en los detalles. Cancel es la opción por defecto.

  • Load recuerda tu confianza para ese código exacto.
  • Editar código de terceros no lo vuelve confiable: la versión editada vuelve a preguntar una vez.
  • El código que escribís en el Lab y los módulos creados con New plugin cargan sin preguntar.
  • Abrir un proyecto nunca ejecuta sus plugins; quedan inactivos hasta que apretás Save & Load. Al cambiar de proyecto se descargan.

Bloques del Lab en juegos exportados

Cuando exportás un juego, PyBlocks incluye en GameData/plugins los módulos cargados que usan las escenas incluidas. Copia la última versión que cargó bien, aunque tu borrador actual tenga errores.

Si una escena usa un bloque del Lab cuyo módulo no está cargado, la exportación se frena y te lista los bloques que tenés que cargar primero. Los paquetes de Python de terceros que importe tu plugin no se incluyen en el juego.