Conceptos fundamentales
La hoja es la única fuente de verdad
Existe exactamente una forma canónica de tus datos: la hoja. Todo lo demás se deriva de ella:
- El IR (Definiciones inmutables) es la forma validada y ensamblada de la hoja.
- Las clases C# generadas son el esquema del IR, hecho fuertemente tipado.
- Los ScriptableObjects generados mediante bake son los valores del IR, hechos cargables — una caché de consulta, nunca una verdad independiente.
Toda modificación pasa por la hoja y debe superar la validación de reimportación para volverse real. Editar un SO generado mediante bake directamente crearía una segunda verdad y evitaría la validación, así que el producto deliberadamente no lo admite como flujo de trabajo.
(El interruptor de "edición de prueba" del inspector existe para experimentos temporales en tiempo de ejecución. Nunca se escribe de vuelta, y la reimportación lo borra.)
Por qué esto importa: un proyecto que trata el SO como la fuente de verdad termina con datos no validados que se desvían de la hoja, sin ninguna forma de reconciliarlos. Aquí, la reconciliación es estructural — siempre regeneras a partir de la hoja.
El IR — un ensamblado inmutable y validado
El IR es lo que produce la validación. Para cada pestaña, contiene una SheetTable (esquema + registros) cuyas celdas ya son valores tipados: int, float, valores de enum, referencias de registro, referencias de asset, listas, tipos de plugin personalizados.
Propiedades clave:
- Sin ensamblaje parcial. Si existe un solo error en cualquier lugar, el IR no se construye (
ImportResult.Success == false ⇔ Registry == null— un invariante estricto). - Sin nulls. Una celda opcional vacía materializa de inmediato el valor predeterminado de su tipo, marcada como
IsDefaulted; los consumidores nunca necesitan comprobar null. - Inmutable. El IR es de solo lectura después del ensamblaje; las salidas (codegen, bake, exportación) lo leen, nunca lo modifican.
La canalización
fetch → parse markers/schema → parse cells → validate (keys, references,
@overlap, asset keys, domain rules) → assemble IR → codegen (.cs) → bake (SO)
└──────────────── collect ALL diagnostics ────────────────┘- La validación lo recopila todo. Obtienes la lista completa de problemas en una sola ejecución — dónde / qué / por qué / cómo, por cada error — en lugar de corregir un error por cada reimportación.
- El codegen es la última etapa, después de la validación y el ensamblaje de valores, porque escribir archivos
.csactiva un domain reload. La canalización está estructurada para que la recarga sea segura y la cadena se reanude automáticamente después de ella. - Los errores son objetos estructurados, representados como frases. Cada error incluye la pestaña, la fila (base 1), y la letra de columna y el nombre de campo. También incluye el valor causante, la regla infringida y una sugerencia accionable (con propuestas de coincidencia más cercana para errores tipográficos). Los mismos objetos también se representan como coordenadas de máquina para registros/CI.
La cadena automática de importación
Cuando un esquema es nuevo o ha cambiado, una ejecución de importación hace internamente dos cosas:
- Escribe el código generado → Unity compila → domain reload.
- Después de la recarga, la cadena se reanuda por sí sola y completa el bake.
Nunca tienes que volver a activar nada manualmente. Si la compilación falla (por ejemplo, tu código de juego hace referencia a un campo que un renombrado acaba de cambiar), la cadena aborta de forma segura con una frase accionable en la consola en lugar de entrar en bucle (límite de 3 intentos, registro de reanudación).
Tipado fuerte, sin análisis en tiempo de ejecución
El codegen lee @name / @type / @desc y, por cada pestaña Foo, emite:
FooDefinition— una clase de registro fuertemente tipada, un campo por columna;@descse convierte en el comentario de documentación XML y en el tooltip del inspector.FooDatabase : DefinitionDatabase— el SO contenedor por pestaña, conRecords, búsquedas de id diferidas (lazy) y unSchemaFingerprint.
El bake escribe campos realmente tipados — cero análisis de texto en tiempo de ejecución, sin reflexión en tiempo de ejecución —, lo que lo hace seguro para IL2CPP (sin riesgos de stripping).
Carga por dirección — cómo la caché se mantiene compartible
Los SO generados mediante bake son cachés específicas de cada máquina, con GUID específicos de cada máquina, así que las referencias directas desde una escena hacia ellos se romperían entre máquinas. En su lugar:
- La importación registra automáticamente cada SO de base de datos en el grupo de Addressables
SheetForge, en la dirección estable"SheetForge/{tab}"(los nuevos bakes vuelven a enlazar el nuevo GUID a la misma dirección; las pestañas eliminadas se limpian). - El código del juego carga por dirección:
SheetForgeDatabases.LoadAsync<FooDatabase>("Foo"). - El asset del grupo de Addressables está en gitignore y es autorreparable (se recrea mediante la importación cuando falta).
Baselines — cómo el ciclo de ida y vuelta preserva tu hoja
Al importar, se guarda una instantánea normalizada de la estructura de cada pestaña (filas de marcadores, orden de columnas, comentarios, texto escrito por humanos) como el baseline. Luego, la exportación intercambia los valores actuales del SO dentro de la estructura del baseline.
Así, un ciclo hoja → importación → exportación → hoja preserva tu hoja al 100% estructuralmente, y preserva los valores semánticamente:
1.0↔1está permitido porque el valor es idéntico.- Los floats usan el formato de ida y vuelta más corto.
- El separador decimal siempre es
., independiente de la configuración regional.
Qué se confirma y qué se regenera
| Artefacto | Política |
|---|---|
| Hojas (archivos locales) / hoja de Google | La verdad. Confirmada / compartida. |
SO de base de datos generados mediante bake (Assets/SheetForgeBaked) | Caché en gitignore específica de cada máquina — regenera ejecutando una importación. |
Código generado (Assets/SheetForgeGenerated) | Confirmarlo (commit) es la recomendación. Es el código fuente propio de tu proyecto, vive fuera de Assets/SheetForge, así que reinstalar el producto no puede borrarlo, y confirmarlo significa que un clon nuevo compila antes de que nadie ejecute una importación. La salida es determinista, así que las importaciones de tus compañeros producen bytes idénticos. Ponerlo en gitignore es una alternativa válida; la siguiente importación lo regenera. Un proyecto anterior a este valor predeterminado sigue generando en Assets/SheetForge/Runtime/Generated hasta que esa carpeta quede vacía; consulta Primeros pasos. |
Asset del grupo de Addressables SheetForge | En gitignore, autorreparable. No confirmes el diff de una línea en los ajustes que genera su primera creación. |
La propia carpeta Generated de un paquete de dominio | Decisión propia del paquete. El ejemplo incluido SheetForge.PluginDemo confirma su código generado para que la demo compile de inmediato al importarla. |
| Asset de ajustes de importación | Gestión tuya; mantén las rutas de la clave de cuenta de servicio fuera del repositorio (usa la variable de entorno SHEETFORGE_SHEETS_KEY). |
Extensión sin modificación
Los contratos de registro permiten que los plugins se sumen a la canalización con cero modificaciones al Core:
- analizadores de tipo de celda (incluidos los tipos wrapper), validadores de dominio, contribuyentes de aristas;
- marcadores estructurales personalizados, plantillas de "Crear hoja", proveedores de origen de importación;
- los overrides de lienzo, registros de código, widgets, acciones, widgets de celda, preajustes de color y cadenas de UI de Data Studio.
Core nunca hace referencia a un paquete de dominio; la dependencia unidireccional la impone el compilador. La lista autorizada — y su recuento — está en Creación de plugins.
Páginas relacionadas
- Sintaxis de la hoja — la gramática de marcadores y tipos que interpreta el analizador
- Data Studio — la creación de contenido sobre este modelo
- Fuentes, exportación y envío — la mecánica del ciclo de ida y vuelta
- Núcleo de creación — el motor debajo de la ventana de creación