Volver al portfolio

Proyecto personal / Herramientas para assets y workflows

AssetGuy

AssetGuy es una CLI en Rust para consultar, organizar, descargar e instalar los assets que posees en Fab. Para el desarrollo Unreal en Windows, combina filtros de versión del motor y estado de descarga, mantiene categorías propias e instala el asset elegido en un proyecto o motor.

¿Cuándo usar AssetGuy en lugar de la biblioteca del launcher?

Si la pregunta es «¿qué packs poseo, compatibles con esta versión de Unreal, que aún no he descargado?», navegar por tarjetas exige buscar y comprobar cada elemento. assetguy library engine UE5.8 uncached consulta el catálogo almacenado. Las categorías por reglas organizan nuevos assets tras sync; la CLI permite repetir consultas y usar la salida JSON en scripts.

La ventaja está en gestionar la biblioteca: consultar sin cargar miniaturas ni pedir datos a Fab, separar descarga e instalación e inspeccionar el destino antes de copiar. Es una alternativa a ese flujo del launcher, no sustituye toda la aplicación. Fab y Windows funcionan hoy; PostgreSQL ya permite compartir el catálogo, mientras que la caché compartida de archivos y la GUI siguen previstas.

  • Rust
  • Tokio
  • SQLite
  • PostgreSQL
  • Windows
Terminal de AssetGuy mostrando assets filtrados por compatibilidad con Unreal Engine 5.8 y estado no descargado
Captura existente del proyecto: assetguy library engine UE5.8 uncached. El pie indica el alcance y los metadatos ausentes; las cifras pertenecen a la biblioteca capturada.

01 / Contexto

Una biblioteca grande dificulta la selección de assets

El punto de partida fue el esfuerzo de encontrar un asset en una cuadrícula, verificar su compatibilidad y saber si los archivos estaban en disco. El launcher reúne esas preguntas en la navegación visual. Necesitaba consultas combinables sobre la biblioteca poseída, con resultados legibles en terminal y utilizables en scripts.

Elegí un catálogo consultable a partir del estado local del launcher y los metadatos obtenidos durante sync. Evitar consultas al marketplace aligera la lectura, pero implica que el catálogo representa la última sincronización, no el estado remoto en tiempo real. Actualizarlo es por tanto explícito. Provider, almacenamiento, descarga e instalación tienen fronteras separadas porque cambian por razones diferentes.

De la sincronización a la instalación de un asset

  1. 01

    Sincronización

    assetguy sync registra los assets poseídos y después enriquece sus metadatos. Autenticación y red pertenecen a operaciones explícitas; consultar la biblioteca no inicia una sincronización.

  2. 02

    Consulta e inspección

    assetguy library engine UE5.8 uncached filtra el catálogo almacenado. assetguy info "Blockout Tools Plugin" muestra detalles y versiones disponibles antes de elegir los archivos.

  3. 03

    Descarga e instalación

    assetguy download llena la caché. assetguy add, assetguy new y assetguy install son operaciones distintas para contenido de proyecto, un proyecto completo y un plugin de motor; sus argumentos identifican el asset y el destino.

El catálogo se consulta sin contactar con Fab. Con SQLite es totalmente local; PostgreSQL consulta el servidor configurado, no el marketplace.

02 / Diseño y arquitectura

Decisiones de arquitectura y sus consecuencias

Catálogo local

Consultas al catálogo separadas de operaciones de red

assetguy library lee la base configurada. assetguy sync la actualiza; assetguy search consulta el catálogo público de Fab; assetguy download obtiene archivos. Esto explicita el coste de cada acción. assetguy add exige los archivos en caché y, cuando faltan, indica el comando de descarga en lugar de transferir gigabytes silenciosamente.

Las URL de miniaturas llegan con los metadatos, pero descargar imágenes es opcional: el terminal no las dibuja y una biblioteca puede contener gigabytes de imágenes. La CLI permite estabilizar el comportamiento antes de que una GUI dependa de él.

El catálogo puede quedar desactualizado entre sincronizaciones. Acepté ese compromiso para que consultar tenga un coste previsible e independiente del marketplace. Los metadatos ausentes siguen visibles: una lista vacía no demuestra que no existan assets compatibles.

Límite del provider

Contratos orientados a operaciones del provider

La biblioteca poseída, los detalles públicos, la búsqueda y la CDN de Fab tienen requisitos de autenticación distintos. Un cliente HTTP autenticado genérico trasladaría supuestos incorrectos entre rutas. El contrato describe operaciones: compras, detalle de listing, autenticación y entrega.

Los roles y capacidades separados permiten nombrar una operación sin soporte. Fab es el provider implementado hoy. El límite de la descarga es DownloadPlan: el provider convierte su manifiesto en un plan; obtención y ensamblado usan ese plan sin depender de los tipos de la API de Epic.

Esta frontera permite probar los flujos sin detalles HTTP y concentra los cambios de la API Fab en su provider. Todavía no demuestra soporte para otra tienda: un segundo provider deberá cumplir esos contratos con sus propios casos reales.

Elección de almacenamiento

Un backend configurado y cuatro roles de storage

SQLite es la opción sin configuración; PostgreSQL ya está implementado. El backend elegido guarda catálogo, clasificación y estado de descargas/instalaciones. Cuatro roles limitan el acceso: AssetStore, CatalogWriteStore, CurationStore y DownloadStore. Una descarga no necesita reescribir categorías.

Los contratos de almacenamiento usan llamadas síncronas acordes con el driver SQLite bloqueante; las operaciones de red y provider son asíncronas. El SQL específico pasa por un límite de dialecto. El backend es configuración persistente; una conexión inválida falla explícitamente sin abrir otra biblioteca. Cambiar de banco no migra los datos existentes.

SQLite es el valor predeterminado para que el uso individual no requiera administrar un servidor. PostgreSQL aporta un catálogo común con el coste de conexiones, credenciales y operación del banco. Compartir metadatos y rutas no pone los archivos a disposición de otras máquinas; requiere la caché compartida aún no implementada.

Búsqueda y clasificación

Categorías por reglas y filtros independientes

Las categorías propias expresan reglas en lugar de un conjunto fijo de etiquetas. Los nuevos assets sincronizados pueden entrar automáticamente en esa organización. Versión del motor, formato, categoría de tienda y estado de caché son filtros distintos.

Las versiones Unreal se comparan por componentes: UE4.1 no debe significar UE4.10. Motor y formato permanecen separados; un formato Unity no implica que Fab proporcione versiones de Unity. Los metadatos ausentes y la cobertura parcial se informan para no confundir resultados vacíos con conocimiento completo del marketplace.

Sincronización

Paginación secuencial, enriquecimiento paralelo

Sync obtiene primero la lista poseída, cuya paginación por cursor es secuencial. Después enriquece los assets con workers paralelos limitados. El presupuesto de peticiones controla la presión sobre la API sin presentarse como porcentaje del ancho de banda.

La lista poseída usa la sesión de la cuenta; los detalles públicos usan un cliente anónimo según el comportamiento observado de la API. Un listing retirado puede seguir siendo poseído y descargable; un tamaño ausente es desconocido, no cero. Inspeccionar el manifiesto permite conocer por separado los tamaños Unreal.

Ensamblado de la descarga

Montaje ordenado y memoria limitada en descargas

Las descargas obtienen chunks en paralelo pero ensamblan archivos con un writer ordenado, calculando SHA1 durante la escritura. Los archivos terminados y verificados forman el estado de reanudación; la identidad del manifiesto evita mezclar builds. Los archivos salen del directorio parcial al terminar.

Los chunks reutilizados tienen una caché de memoria limitada. El plan conoce el orden de escritura y descarta el chunk cuyo próximo uso está más lejano. Una recuperación adicional ocasional permite un techo de memoria previsible sin almacenar dos veces el asset completo en disco.

La escritura ordenada simplifica verificación y reanudación, pero puede esperar un chunk retrasado aunque otros ya hayan llegado. El límite de caché puede exigir volver a obtener un chunk. La decisión prioriza integridad y memoria previsible frente a maximizar el paralelismo a cualquier coste.

Instalación controlada

Instalación según el tipo y el manifiesto

Los packs de contenido van a Content; los proyectos completos se copian como proyectos; los plugins siguen las rutas del manifiesto. Dry run permite inspeccionar la acción y las colisiones requieren force explícito. Las copias se preparan en el volumen de destino; el staging del motor queda fuera del scanner de plugins.

La instalación exige la raíz exacta de un motor registrado. Los archivos preceden a los registros del launcher: manifiesto, item, lista de instalaciones y EOSH se mantienen. Copias de respaldo y relectura protegen la lista. El launcher debe estar cerrado porque puede reescribir esos archivos desde su estado en memoria.

Instalar contenido en un proyecto y un plugin en un motor afecta a estructuras distintas. Los comandos separados hacen explícitos el destino y el efecto. Los registros del launcher son la integración más sensible: copiar la carpeta no basta para que la herramienta Epic reconozca instalación y eliminación.

Estado y credenciales

Configuración, credenciales y registros con ciclos de vida distintos

La configuración está en el perfil itinerante; credenciales OAuth, caché y auditoría en el local. El login usa el navegador y devuelve un código ocultado en la auditoría según la identidad del comando. Las contraseñas del banco se proporcionan por separado de la URL almacenada.

El estado del launcher es de solo lectura para consulta y sincronización. install, uninstall y repair son las excepciones explícitas que escriben sus registros. La auditoría mensual local registra operaciones; doctor expone problemas de integridad sin pedir al desarrollador que invente consultas de diagnóstico.

Detalle de un asset con versiones Unreal compatibles, metadatos, tamaño desconocido y comando de descarga
Captura existente: assetguy info "Blockout Tools Plugin". El tamaño desconocido se explica en lugar de mostrarse como cero, junto al siguiente comando.

03 / Dentro del código

Operaciones de assets en el core; presentación en la CLI

assetguy-core

Contratos provider, almacenamiento, filtros, sync, descargas verificadas, instalación e integración launcher. La CLI usa estas operaciones; una futura GUI pretende reutilizarlas.

assetguy-cli

Enruta comandos con clap, interpreta palabras clave combinables y muestra tablas, JSON y progreso. El formato del terminal queda separado de las operaciones sobre assets.

Tokio / DownloadPlan

Red asíncrona y pools limitados conviven con ensamblado ordenado. Los manifiestos de providers se traducen antes de llegar a ese proceso.

SQLite / PostgreSQL

Dos backends comparten contratos por rol y pruebas de conformidad semántica. SQLite también lee datos del launcher y conserva la auditoría local, incluso con PostgreSQL.

Cómo se verifica el comportamiento

Las comprobaciones incluyen cargo fmt, clippy con advertencias como errores, pruebas unitarias y verificaciones manuales con assets reales. Una suite independiente del backend verifica la misma semántica en SQLite y PostgreSQL. La instalación requiere comprobar el editor: una prueba unitaria no demuestra que el contenido aparece en Unreal ni que el launcher puede quitar un plugin.

04 / Trabajo en curso

Qué está implementado y qué sigue pendiente

En desarrollo

AssetGuy es una CLI Windows en desarrollo inicial, bajo licencia MIT y sin afiliación con Epic Games. Consulta, categorías, OAuth, sync, búsqueda pública, descargas, instalación de contenido/proyectos Unreal, plugins y ambos backends están implementados. Comandos y comportamiento pueden cambiar antes de 1.0.

Las próximas direcciones son una caché de archivos compartida, un segundo provider y una GUI sobre el core existente. El banco compartido ya existe, pero no distribuye por sí solo los archivos entre máquinas. Instalar en Unity y Godot es un objetivo más amplio; las rutas funcionales descritas aquí son de Unreal.

Explora el proyecto

El README documenta comandos, filtros, configuración de bases de datos, descargas, protecciones de instalación y límites actuales. El código muestra las fronteras entre CLI, core e integración Fab.

Lee la documentación en GitHub

Contacto

Ciudad de Québec, QC, Canadá / Disponible para oportunidades

Estoy abierto a oportunidades en desarrollo de software, programación de herramientas y gameplay, así como a puestos de artista 3D junior. Si mi experiencia encaja con tu equipo, estaré encantado de conversar a través de mis perfiles sociales.