Documentos de Asset Core

Documentación del motor de estado mundial determinista y referencias de API.

Documentos de Decision Gate

Contenedores y Activos

Los contenedores son la abstracción fundamental de almacenamiento en Asset Core. Almacenan activos con diferentes características espaciales dependiendo de su tipo. La idea clave es que el mismo modelo de transacción se aplica a todos los tipos de contenedores, por lo que se pueden modelar dominios diversos sin cambiar la infraestructura.

Problema que este concepto resuelve

La gestión de activos del mundo real implica patrones de almacenamiento diversos. Un modelo de datos de talla única o se ajusta en exceso o pierde semánticas críticas, especialmente en sistemas espaciales.

  • Cantidades agregadas (saldos de cuentas, conteos de inventario)
  • Secuencias ordenadas (slots de equipo, listas clasificadas)
  • Disposiciones espaciales (rejillas de almacén, placas de laboratorio)

Un único modelo de almacenamiento no puede representar eficientemente todos estos patrones. Asset Core resuelve esto proporcionando múltiples tipos de contenedores, cada uno optimizado para su dimensión espacial mientras comparte una interfaz de operación común. Esto te brinda tanto fidelidad como consistencia.

Ideas principales

Clasificación Dimensional

La parte más difícil de construir sistemas de estado espacial es manejar la discrepancia dimensional entre los patrones de almacenamiento. Los saldos de cuentas son escalares (0D): te importa la cantidad, no la posición. Los espacios de equipo son secuenciales (1D): la posición importa, pero solo en una línea. Las rejillas de almacén son planas (2D): la adyacencia y la colisión importan en dos dimensiones.

La mayoría de los sistemas eligen un modelo y lo estiran de manera incómoda. Almacenan todo en una tabla relacional y pierden la semántica espacial (sin detección de colisiones, sin consultas de adyacencia). Almacenan todo en un grafo y pagan por una estructura que no necesitan (un saldo no necesita coordenadas). Almacenan todo en un almacén de clave-valor genérico e implementan la lógica espacial en el código de la aplicación (reinventando la detección de colisiones para cada dominio).

AssetCore adopta un enfoque diferente: proporcionar el CONTENEDOR ADECUADO para cada necesidad dimensional, pero mantener la interfaz de operación consistente. Los contenedores se clasifican según la dimensionalidad de su espacio de direcciones. Cada tipo añade semántica espacial sin cambiar el sobre de transacción:

TipoDimensiónEspacio de DirecciónCasos de Uso Ejemplo
Balance (balance)0DNinguno (solo agregación)Saldos, totales
Slots (slots)1DÍndices secuencialesEquipos, listas ordenadas
Grid (grid)2DCoordenadas de rejillaPlacas, almacenes
Línea Continua (continuous_line_1d)1DCoordenada de punto fijo (x)Rieles, actuadores
Plano Continuo (continuous_grid_2d)2DCoordenadas de punto fijo (x, y)Celdas de trabajo de robots, pick-and-place

Este tipo dimensional resuelve un problema real: evita que accidentalmente trates un saldo escalar como una cuadrícula (sin sentido) o que consultes posiciones de ranura desde un plano continuo (error de tipo). El tipo de contenedor codifica el contrato espacial, y las operaciones se validan contra él en el momento de la ejecución.

Lo que ganas: las mismas operaciones (AddFungible, MoveInstance, etc.) se adaptan automáticamente a la geometría del contenedor. Lo que sacrificas: la carga cognitiva de aprender 5 tipos de contenedores en lugar de 1. Creemos que este intercambio te hace más rápido a largo plazo porque tu modelo de dominio coincide con tu modelo mental.

Balances (0D)

Los contenedores de balance mantienen balances fungibles. Úselos cuando solo le importe la cantidad y no la ubicación espacial: libros de cuentas, totales de moneda, grupos de recursos.

Los saldos son 0-dimensionales: no tienen coordenadas, no tienen posiciones, no tienen huella espacial. Un saldo es un contador escalar puro. Esto los convierte en la herramienta adecuada para preguntas de “cuánto”, no para preguntas de “dónde”.

  • Identificado por pares (class_id, key)
  • Las cantidades se agregan sin posición espacial (sin coordenadas x/y)
  • Soporte para operaciones de añadir, eliminar y transferir

Por qué esto es importante: Si almacenaras moneda en un contenedor Grid, tendrías que elegir coordenadas arbitrarias para cada unidad. Si lo almacenaras en Slots, desperdiciarías un slot por unidad y alcanzarías los límites de capacidad instantáneamente. Los saldos te ofrecen una agregación escalar ilimitada, que es lo que realmente es la moneda.

Ejemplo de caso de uso: Un inventario de reactivos en un laboratorio donde se rastrean mililitros de nitrógeno líquido. No te importa DÓNDE está el nitrógeno (está en el tanque), te importa CUÁNTO tienes. Eso es un balance.

{
  "op": "AddFungible",
  "args": {
    "class_id": 100,
    "key": 1,
    "quantity": 500,
    "location": {
      "container_id": 1001,
      "kind": "balance"
    }
  }
}

Lo que ganas: agregación sin sobrecarga espacial. Un balance que contiene 1,000,000 unidades tiene el mismo costo que un balance que contiene 1 unidad; es solo un contador. Lo que sacrificas: consultas espaciales. No puedes preguntar “¿qué hay en la posición (3,5)?” para un balance porque las posiciones no existen. Si necesitas semántica espacial, utiliza contenedores Grid o Continuous en su lugar.

Slots (1D)

Los contenedores de ranura contienen instancias únicas en posiciones secuenciales. Son ideales para equipos, configuraciones o listas ordenadas donde la exclusividad importa más que la geometría.

  • Índices del 1 al N (capacidad configurable)
  • Cada ranura contiene como máximo una instancia
  • Soporte para operaciones de colocar, eliminar e intercambiar

Ejemplo: espacios de equipo en un personaje o posiciones en una cola de procesamiento.

{
  "op": "PlaceInSlot",
  "args": {
    "container_id": 1001,
    "instance_id": 9001,
    "slot_index": 1
  }
}

Cuadrícula (2D)

Los contenedores de cuadrícula añaden geometría espacial. Son la elección adecuada para almacenes, placas de laboratorio y cualquier entorno donde la adyacencia y la colisión sean importantes.

  • Ancho x Alto de la rejilla de celdas
  • Los elementos ocupan múltiples celdas según la forma
  • Soporte para la detección de colisiones y adyacencia

Ejemplo: Una placa de 96 pocillos o una cuadrícula de almacenamiento en almacén.

Los contenedores de cuadrícula pueden contener tanto pilas fungibles (con colocación espacial) como instancias únicas.

Línea Continua (1D)

Los contenedores de línea continua (continuous_line_1d) almacenan instancias a lo largo de un único eje de punto fijo. Las coordenadas de punto fijo garantizan una reproducción determinista sin deriva de punto flotante.

  • Las coordenadas son enteros de punto fijo deterministas (sin flotantes)
  • Las colocaciones deben permanecer dentro de los límites min/max
  • Las comprobaciones de colisión imponen intervalos no superpuestos

Casos de uso: rieles lineales, transportadores con precisión sub-celular y robótica de un solo eje.

Plano Continuo (2D)

Los contenedores de plano continuo (continuous_grid_2d) almacenan instancias en un espacio de trabajo continuo y limitado. Están diseñados para células de trabajo en robótica y tareas de planificación continua.

  • Coordenadas fijas en x/y con redondeo determinista
  • Comprobaciones de colisión de rectángulos orientados (rotación en miligrados)
  • Colocaciones, movimientos y rotaciones con verificación de límites
  • Colocaciones solo de instancia (sin pilas fungibles)

Casos de uso: celdas de trabajo robóticas, tareas de recogida y colocación, y planificación de colisiones métricas.

Instancias vs. Fungibles

Esta distinción refleja el mundo real: la moneda es fungible (tu billete de $20 es intercambiable con el mío), el equipo es único (tu espada específica tiene durabilidad, encantamientos y una historia). El sistema de tipos refuerza esto a nivel de operación.

Los activos fungibles son cantidades intercambiables. Se representan mediante pares de clase y clave y pueden dividirse o fusionarse libremente.

  • Identificado por clase y clave
  • Las operaciones especifican cantidades
  • Puede ser dividido y fusionado libremente

Por qué es importante: los fungibles pueden ser divididos y fusionados libremente, lo que permite operaciones como Distribute (dividir cantidad entre objetivos) y ConsolidateStacks (fusionar en uno). Intentar “dividir” una instancia es un error de tipo que se detecta en el momento de la validación.

Instancias únicas se rastrean individualmente. Están representadas por IDs estables y pueden ser adjuntadas o separadas para formar jerarquías.

  • Tener identificadores globalmente únicos
  • No se puede dividir ni fusionar
  • Puede formar jerarquías padre-hijo a través de adjuntar/desadjuntar

Las instancias únicas no pueden ser divididas ni fusionadas—MoveInstance reubica toda la instancia de forma atómica. La jerarquía padre-hijo para las instancias (Attach/Detach) modela un anidamiento real: una mochila contiene un bolsillo, que contiene pociones. La jerarquía se refleja en las consultas, haciendo que “¿qué hay en este contenedor de forma recursiva?” sea una operación de primera clase.

Clases y Formas

Las clases definen tipos de activos. Son los identificadores canónicos tanto para fungibles como para instancias, y deben estar registrados antes de su uso.

  • Proporcionar metadatos como nombres y banderas opcionales
  • Servir como identificadores estables para saldos fungibles o instancias únicas
  • Debe estar registrado antes de su uso

Las clases tienen un alcance de espacio de nombres: un class_id solo tiene significado dentro de su espacio de nombres. El mismo ID numérico en un espacio de nombres diferente es una clase diferente. Una vez registrado, un ID de clase no puede ser reutilizado para una definición diferente. Esto mantiene la identidad estable para auditoría y reproducción.

Las clases pueden opcionalmente llevar restricciones de comportamiento que se aplican en el momento de la validación de la operación. Estas restricciones son la forma en que codificas los límites del “mundo real” en reglas deterministas:

  • Escala de balance (cuantización de punto fijo para balances)
  • Pisos/techos de saldo mínimo y máximo
  • Tamaño máximo de pila para pilas fungibles
  • Máximo de pilas por contenedor para una clase
  • Capacidad de saldo negativo (permitida explícitamente o no)

Las formas definen huellas espaciales. Permiten que el tiempo de ejecución haga cumplir las reglas de colisión de manera determinista, lo cual es esencial para la corrección.

  • Ancho y alto en celdas de cuadrícula
  • Asociado a una clase y clave de variante opcional
  • Requerido para la colocación del contenedor de cuadrícula

Las variantes se expresan con stack_key. El par (class_id, stack_key) define la identidad fungible y determina qué forma (si es que hay alguna) se requiere para la colocación. Esto permite modelar variantes (tamaño, nivel, condición) sin multiplicar los ID de clase.

Resumen de compatibilidad:

  • Balance: Cantidades fungibles solamente (escala de punto fijo; sin posiciones)
  • Slots: Instancias solamente (una instancia por slot)
  • Rejilla: Pilas o instancias fungibles (formas requeridas para la colocación en múltiples celdas)
  • Continuo 1D/2D: Solo instancias (coordenadas de punto fijo; se requieren formas/intervalos)
{
  "op": "RegisterClass",
  "args": {
    "request": {
      "class_id": 200,
      "flags": 2,
      "name": "Sample Tube"
    }
  }
}

Cómo encaja en el sistema

Validación y despacho

El tipo de contenedor es parte del contrato de operación. Durante la validación L2, el entorno de ejecución verifica el tipo de contenedor, el registro de clases y los requisitos de forma antes de cualquier mutación. La verificación previa utiliza los mismos controles, por lo que una verificación previa exitosa implica que el compromiso pasará si el mundo no ha cambiado.

Ejemplos de cómo se desarrolla esto:

  • AddFungible en el balance incrementa un balance escalar.
  • AddFungible en la cuadrícula requiere registro de forma y comprobaciones de colisión.
  • PlaceInSlot en balance es rechazado (tipo de contenedor incorrecto).

Registro y formas

La clase y el registro de forma residen en el espacio de nombres del registro. Las colocaciones en cuadrícula y continuas consultan el registro para obtener huellas o extensiones, de modo que la colocación sea determinista y segura para la repetición en lugar de ad hoc.

Leer proyecciones y superficies de consulta

Las proyecciones de lectura mantienen índices específicos de contenedores (saldos por clase/clave, ocupación de ranuras, anclajes de cuadrícula). Las respuestas de lectura devuelven cargas útiles tipadas por tipo de contenedor, por lo que las consultas de “contenidos del contenedor” siempre coinciden con la geometría que el contenedor impone.

Ver también