Skip to content

research: GDExtension del Hub para Godot Editor #222

Description

@lobinuxsoft

Descripción

Investigar la viabilidad de crear un GDExtension que integre el Hub de CapyDeploy directamente en el editor de Godot 4.x como un dock/panel. El desarrollador podría buildear su juego en Godot y deployarlo al handheld sin salir del editor.

Contexto

CapyDeploy está orientado a handhelds. Un plugin de Godot cerraría el loop de desarrollo: build → deploy → test, todo desde el editor. Los crates de Rust del proyecto son reutilizables via godot-rust (gdext).

Preguntas a responder

Arquitectura

  • ¿Se puede crear un EditorPlugin con UI (dock panel) via GDExtension en Rust (gdext)?
    • Respuesta preliminar: Sí. EditorPlugin.add_dock() acepta cualquier nodo Control. gdext v0.4.5 soporta #[class(tool, base=EditorPlugin)].
  • ¿Cómo manejar el runtime de tokio dentro de Godot? Los crates actuales (hub-connection, discovery, hub-deploy) dependen de tokio.
    • Respuesta preliminar: Levantar tokio::Runtime en thread separado desde _enter_tree(), comunicar con hilo principal de Godot via std::sync::mpsc. Procesar mensajes en _process().
  • ¿Se pueden reutilizar los crates existentes directamente?
    • capydeploy-protocol — ✅ Puro serde, sin tokio, reutilizable directamente
    • capydeploy-discovery⚠️ Depende de tokio/mdns-sd, necesita capa de adaptación
    • capydeploy-hub-connection⚠️ Depende de tokio-tungstenite, necesita capa de adaptación
    • capydeploy-hub-deploy⚠️ Depende de tokio, necesita capa de adaptación
    • capydeploy-hub-telemetry⚠️ Probable dependencia de tokio

Frontend / UI

  • ¿Se puede reutilizar el frontend Svelte dentro de Godot (WebView)?
    • Respuesta preliminar: No viable. Godot no tiene WebView nativo. Hay que reconstruir la UI con nodos de Godot.
  • ¿Qué componentes nativos de Godot equivalen a nuestra UI actual?
    • Cards → PanelContainer + VBoxContainer + Label
    • Progress bars → ProgressBar (nativo)
    • Tabs → TabContainer / TabBar
    • Log viewer → RichTextLabel (BBCode, colores, scroll)
    • Lista de juegos/agentes → Tree (con columnas) o ItemList
    • Botones → Button, MenuButton
    • Config → SpinBox, CheckBox, OptionButton, LineEdit
  • ¿Se puede lograr un look similar al Hub actual? ¿O se delega al theme del editor?
    • Respuesta preliminar: Se integra con el theme del editor por defecto. Se pueden customizar StyleBoxes si se quiere branding propio, pero lo ideal es respetar el theme del usuario.

Integración con Godot

  • ¿Se puede hookear al proceso de export para auto-deploy?
    • Respuesta preliminar: Sí. EditorExportPlugin tiene _export_begin(features, is_debug, path, flags) y _export_end(). Se podría auto-deployar al terminar la exportación.
  • ¿Se puede interceptar el logger de Godot (print(), push_error(), push_warning())?
    • Respuesta preliminar: No directamente. No hay API para interceptar la consola del editor. Se podrían registrar log handlers custom, pero no capturar print() de scripts del usuario. La consola del agente remoto (console log del juego corriendo en el handheld) seguiría llegando por WebSocket como ahora.
  • ¿Se puede acceder a export presets y build output path?
    • Respuesta preliminar: Sí, via EditorExportPlugin.get_export_preset() durante export. ProjectSettings accesible como singleton.
  • Hook pre-ejecución: _build() -> bool — ¿útil para validar conexión antes de deploy?

Telemetría

  • La telemetría del handheld (CPU, GPU, RAM, FPS) sigue viniendo del agente remoto via WebSocket. No cambia.
  • Godot expone métricas locales via Performance singleton pero son del editor, no del dispositivo remoto.
  • ¿Tiene sentido mostrar telemetría del handheld en el editor? Sí — mientras testeas el juego remoto, ves el rendimiento en tiempo real.

Networking

  • ¿WebSocket desde GDExtension?
    • Opción A: WebSocketPeer nativo de Godot (hay que pollear en _process())
    • Opción B: Crates de Rust (tokio-tungstenite, mdns-sd) en thread de tokio separado
    • Recomendación: Opción B para reutilizar crates existentes
  • Godot NO tiene mDNS nativo. Discovery debe venir del crate Rust.

Distribución y Godot Asset Library

  • Estructura del addon:
    addons/capydeploy/
      plugin.cfg
      capydeploy.gdextension
      bin/
        linux/libcapydeploy.so
        windows/capydeploy.dll
        macos/libcapydeploy.dylib
      icons/
    
  • Usuarios NO necesitan compilar. Se distribuyen binarios precompilados.
  • Requisitos de la Asset Library:
    • Repo Git público
    • LICENSE obligatorio
    • .gitignore obligatorio
    • Nombre y descripción en inglés
    • Icono cuadrado ≥128x128px
    • Sin submodulos git
    • Revisión manual (varios días)
  • ¿Binarios nativos en la Asset Library? No hay prohibición explícita. Otros GDExtensions populares (godot-jolt, godot-steam) se distribuyen con binarios precompilados.
  • ⚠️ Licencia: CapyDeploy es AGPL-3.0. Muchos devs de Godot evitan AGPL. Evaluar licencia dual o MIT específica para el plugin del editor (es editor-only, no afecta al juego exportado).

CI/CD

  • GitHub Actions para cross-compilation: Linux x86_64, Windows x86_64, macOS (x86_64 + arm64 universal binary)
  • macOS es problemático sin runner nativo. Evaluar cross-rs o GitHub macOS runners.

Riesgos

Alto

  • Tokio runtime dentro de Godot — Levantar runtime en background y bridgear con hilo principal. Posibles deadlocks si no se maneja bien.
  • Rebuild completo de UI — No se reutiliza nada del frontend Svelte. Todo desde cero con nodos Godot.
  • Cross-compilation macOS — Sin runner nativo es complicado.

Medio

  • Registro automático del plugin — Los plugins gdext se cargan siempre que el GDExtension esté en el proyecto. No se pueden desactivar desde Project Settings (a diferencia de plugins GDScript).
  • Godot version coupling — Cada versión mayor puede romper compatibilidad del GDExtension ABI.
  • Tamaño del binario — tokio + tungstenite + mdns-sd + serde compilado ≈ 5-15 MB.

Bajo

  • Editor-only — Marcado como @tool. No afecta al juego exportado.
  • Hot reload limitado — gdext requiere reiniciar el editor al recompilar (aunque reloadable = true es experimental desde Godot 4.2).

Estructura propuesta

# Nuevo crate en el workspace
crates/hub-gdext/
  Cargo.toml          # Depende de protocol, discovery, hub-connection, hub-deploy
  src/
    lib.rs            # Entry point GDExtension
    plugin.rs         # EditorPlugin (dock, lifecycle)
    ui/               # Nodos de Godot para la UI
    bridge.rs         # Tokio runtime <-> Godot main thread

O como repo separado si la Asset Library lo requiere.

Spike previo

Antes de la implementación completa, crear un prototipo mínimo que valide:

  1. Un EditorPlugin en Rust (gdext) con un dock panel
  2. Un tokio::Runtime en background con WebSocket a un agent real
  3. Discovery mDNS funcionando dentro de Godot
  4. Una Tree o RichTextLabel mostrando datos del agente en vivo

Referencias

Decisión

Pendiente de spike/prototipo.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions