fad4006f60
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
242 lines
8.5 KiB
Markdown
242 lines
8.5 KiB
Markdown
---
|
|
id: "0072i"
|
|
title: "gamedev — editor visual `game_editor` (scene tree, asset browser, inspector)"
|
|
status: pendiente
|
|
type: feature
|
|
domain:
|
|
- gamedev
|
|
scope: app-scoped
|
|
priority: media
|
|
depends:
|
|
- "0072b"
|
|
- "0072c"
|
|
blocks: []
|
|
related: []
|
|
created: 2026-05-10
|
|
updated: 2026-05-17
|
|
tags:
|
|
- gamedev
|
|
- cpp
|
|
- editor
|
|
- tooling
|
|
---
|
|
|
|
## Objetivo
|
|
|
|
App PC `cpp/apps/game_editor/` estilo `shaders_lab` / `chart_demo`: editor visual basado en ImGui que abre/edita/exporta proyectos de juego usando los formatos del runtime (sub-issues 0072b, 0072c). NO es Godot empotrado — es un editor minimalista construido con las funciones del registry, hot-reloadable, integrado en el ecosistema fn.
|
|
|
|
## Filosofia
|
|
|
|
| Concepto | Decision |
|
|
|---|---|
|
|
| Visual scripting | NO — todo en C++ con hot reload (dylib opcional) |
|
|
| Scene format | JSON o binario (mismo `.pak` del runtime) |
|
|
| Hot reload assets | Si — file watcher + reload en runtime conectado |
|
|
| Live preview | Si — el editor lanza el runtime como subprocess y se comunica via IPC |
|
|
| Multi-platform editor | NO — solo PC. Mobile no edita, solo ejecuta. |
|
|
|
|
## Layout
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ Menu: File · Edit · View · Build · Help │
|
|
├─────────┬───────────────────────────────────────┬───────────┤
|
|
│ Scene │ │ Inspector │
|
|
│ Tree │ │ │
|
|
│ │ Scene Viewport │ - Pos │
|
|
│ - Root │ (live runtime via IPC) │ - Sprite │
|
|
│ - Bg │ │ - Script │
|
|
│ - Pl │ │ ... │
|
|
│ - En │ │ │
|
|
├─────────┼───────────────────────────────────────┼───────────┤
|
|
│ Assets │ │ Layers │
|
|
│ Browser │ │ Anim │
|
|
│ │ │ Timeline │
|
|
└─────────┴───────────────────────────────────────┴───────────┘
|
|
```
|
|
|
|
Implementado con `AppShell` style + ImGui dockspace + paneles del registry.
|
|
|
|
## Paneles a crear
|
|
|
|
### Scene tree
|
|
|
|
`cpp/functions/gamedev/scene_tree_panel.{cpp,h,md}` (impure):
|
|
|
|
```cpp
|
|
struct SceneNode {
|
|
std::string id;
|
|
std::string name;
|
|
std::string type; // "sprite", "tilemap", "particle", "audio", "trigger"
|
|
Vec2 pos, scale;
|
|
float rotation;
|
|
std::vector<std::string> children;
|
|
nlohmann::json props; // Type-specific data
|
|
};
|
|
|
|
void scene_tree_render(SceneTreeState& s, std::vector<SceneNode>& nodes,
|
|
std::string& selected);
|
|
```
|
|
|
|
Drag-reparent, multi-select, search, lock/visibility per node.
|
|
|
|
### Inspector
|
|
|
|
`cpp/functions/gamedev/inspector_panel.{cpp,h,md}` (impure):
|
|
|
|
Inspecciona el nodo seleccionado, muestra sus props en widgets ImGui, escribe cambios en el modelo. Genera UI desde un schema JSON declarado por tipo de nodo:
|
|
|
|
```json
|
|
{
|
|
"sprite": [
|
|
{ "name": "atlas", "type": "asset_ref", "asset": "atlas" },
|
|
{ "name": "frame", "type": "string" },
|
|
{ "name": "tint", "type": "color" },
|
|
{ "name": "z_order", "type": "int", "min": -100, "max": 100 }
|
|
]
|
|
}
|
|
```
|
|
|
|
Reusable: el mismo panel sirve para inspeccionar entities en otras apps. Generaliza `params_schema` del registry.
|
|
|
|
### Asset browser
|
|
|
|
`cpp/functions/gamedev/asset_browser_panel.{cpp,h,md}` (impure):
|
|
|
|
Grid de thumbnails. Filtrable por tipo (sprite, sound, shader, script). Drag a la viewport o al inspector.
|
|
|
|
Backend: directorio del proyecto + watcher (`fn::file_watcher` ya existe en registry?).
|
|
|
|
### Tilemap editor
|
|
|
|
`cpp/functions/gamedev/tilemap_editor_panel.{cpp,h,md}` (impure):
|
|
|
|
Edita layers de tilemap. Brush painting, eraser, fill bucket, picker. Edita formato compatible con `tilemap_compile_cpp_gfx` (de 0072c).
|
|
|
|
### Animation timeline
|
|
|
|
`cpp/functions/gamedev/anim_timeline_panel.{cpp,h,md}` (impure):
|
|
|
|
Reusa `cpp/functions/.../animation_curves` (ya existe del issue 0031). Crea state machines simples: idle/walk/jump por sprite.
|
|
|
|
### Shader graph
|
|
|
|
Reusa `cpp/functions/gfx/dag_*` (ya existe). Editor visual de shaders 2D que produce GLSL ES 300.
|
|
|
|
## Live preview via IPC
|
|
|
|
El editor lanza el runtime como subprocess en una ventana separada y le envia comandos via stdin/stdout JSON-RPC (o socket local):
|
|
|
|
```
|
|
editor → runtime: { "method": "load_scene", "params": { "path": "/tmp/preview.json" } }
|
|
runtime → editor: { "result": { "ok": true } }
|
|
|
|
editor → runtime: { "method": "select_node", "params": { "id": "player" } }
|
|
editor → runtime: { "method": "set_prop", "params": { "id": "player", "key": "tint", "value": [1,0,0,1] } }
|
|
```
|
|
|
|
El runtime, al recibir un cambio, repinta el frame. Usuario ve cambios al instante.
|
|
|
|
Funciones nuevas:
|
|
- `cpp/functions/core/json_rpc_server.{cpp,h,md}` (impure)
|
|
- `cpp/functions/core/json_rpc_client.{cpp,h,md}` (impure)
|
|
|
|
Si ya existe algo en el registry para IPC, reusarlo. Buscar en FTS5.
|
|
|
|
## Project format
|
|
|
|
```
|
|
my_game/
|
|
project.json # Metadata, scenes, build targets
|
|
scenes/
|
|
main_menu.json
|
|
level_1.json
|
|
assets/
|
|
sprites/
|
|
player.png
|
|
enemy.png
|
|
sounds/
|
|
jump.wav
|
|
fonts/
|
|
Roboto.ttf
|
|
shaders/
|
|
bg_gradient.glsl
|
|
scripts/ # Si hay scripting (futuro)
|
|
build/ # Output del asset_compiler + binarios
|
|
```
|
|
|
|
`project.json` schema documentado en `cpp/GAMEDEV.md`.
|
|
|
|
## Build button
|
|
|
|
Toolbar tiene botones:
|
|
- **Build PC** → invoca `build_pc_cpp_pipelines.sh` para la app objetivo
|
|
- **Build WASM** → invoca `build_wasm_cpp_pipelines.sh` (issue 0072d)
|
|
- **Build Android** → invoca `build_android_cpp_pipelines.sh` (issue 0072g)
|
|
- **Build iOS** → muestra mensaje "Build iOS requires mac" si no estamos en mac (0072h)
|
|
|
|
Output del build se streamea en un panel de log integrado.
|
|
|
|
## Persistencia
|
|
|
|
- `project.json` — formato del proyecto, versionado en git por el usuario.
|
|
- `~/.fn_game_editor/recent.json` — proyectos recientes.
|
|
- `<exe_dir>/local_files/editor_settings.json` — settings del editor (paneles abiertos, layout, etc.). Reusa convencion `fn::local_path` (ver `cpp_apps.md`).
|
|
|
|
## e2e_checks
|
|
|
|
```yaml
|
|
e2e_checks:
|
|
- id: build
|
|
cmd: "cmake --build build --target game_editor -j"
|
|
- id: self_test
|
|
cmd: "./build/cpp/apps/game_editor/game_editor --self-test"
|
|
timeout_s: 30
|
|
- id: open_sample_project
|
|
cmd: "./build/cpp/apps/game_editor/game_editor --open samples/platformer/project.json --headless --quit-after 2s"
|
|
timeout_s: 30
|
|
```
|
|
|
|
## Estructura
|
|
|
|
```
|
|
cpp/apps/game_editor/
|
|
CMakeLists.txt
|
|
app.md
|
|
main.cpp
|
|
data.{cpp,h} # Project / Scene CRUD
|
|
views.{cpp,h} # Composicion de paneles
|
|
ipc.{cpp,h} # JSON-RPC con runtime
|
|
samples/
|
|
platformer/ # Proyecto demo
|
|
project.json
|
|
scenes/...
|
|
```
|
|
|
|
## Reusabilidad
|
|
|
|
Muchos paneles (`scene_tree_panel`, `inspector_panel`, `asset_browser_panel`) son utiles fuera de gamedev. Otras apps del registry (`graph_explorer`, `kanban`) podrian reusarlos. Diseñarlos parametrizables desde el dia 1.
|
|
|
|
## Criterio de exito
|
|
|
|
- [x] `game_editor` abre, lista escenas, edita un sprite, exporta y se ve el cambio en runtime.
|
|
- [x] Live preview con IPC funciona (latencia < 100ms).
|
|
- [x] Hot reload de assets cuando cambian en disco.
|
|
- [x] Build PC + WASM desde el editor (botones funcionando).
|
|
- [x] Sample project `platformer` jugable end-to-end.
|
|
- [x] Paneles documentados como funciones del registry, reusables.
|
|
|
|
## No-objetivos
|
|
|
|
- Editor mobile-friendly. Solo PC.
|
|
- Visual scripting. Codigo en C++ + scripting opcional (0072l).
|
|
- Multi-user collab.
|
|
- VCS integrado — usuario usa git fuera del editor.
|
|
- Asset store / marketplace.
|
|
|
|
## Riesgos
|
|
|
|
1. **Inspector schema-driven** — abstraccion potencialmente sobreingenierizada. Empezar concreto, abstraer cuando haya 3 tipos de nodos.
|
|
2. **IPC latency** — JSON-RPC sobre stdin/stdout puede tener overhead. Si pasa, evaluar shared memory.
|
|
3. **Tilemap editor UX** — no es trivial. Reservar tiempo. Reusar lo que se pueda de Tiled (formato `.tmx`).
|