--- id: "0072l" title: "gamedev — scripting opcional (wren / lua / hot reload C++ dylib)" status: deferred type: feature domain: - gamedev scope: multi-app priority: baja depends: - "0072k" blocks: [] related: [] created: 2026-05-10 updated: 2026-05-17 tags: - gamedev - cpp - scripting --- ## Objetivo Decidir si vale la pena añadir scripting al stack y, en su caso, integrarlo. Es un sub-issue **diferido**: solo se aborda cuando la fricción de iterar gameplay en C++ (recompilar) sea concretamente dolorosa, no antes. ## Cuando reconsiderar Triggers para sacar este issue del modo `deferred`: - Recompilar `engine_demo` tras un cambio gameplay supera consistentemente 10s incluso con ccache + unity build. - Aparece un caso real de iterar gameplay en runtime sin reiniciar (designers no-developers tocando logica). - Aparece la necesidad de modding por usuarios finales. Mientras eso no pasa: **no añadir scripting**. Cada lenguaje de scripting: - Suma ~50-200 KB al wasm. - Multiplica superficie de bugs (FFI bindings). - Confunde la cultura del registry (¿dónde vive el "codigo de juego"? ¿C++ o scripts?). ## Opciones ### Opcion A — wren - Pequeño (~50 KB). - Sintaxis tipo Lua/Smalltalk. - API C limpia. - Single-author (Bob Nystrom), actualizaciones lentas. ### Opcion B — lua / luajit - Lua estandar: ~200 KB. LuaJIT no compila a WASM, descartar. - Mas usuarios, mas docs. - Sintaxis familiar. - Bindings: sol2 (~5K LoC, pero header-only) o tolua manual. ### Opcion C — quickjs - JS subset. - ~700 KB. Demasiado para nuestro budget. - Descartar a menos que necesitemos JS por compatibilidad con codigo crypto. ### Opcion D — hot reload C++ via dylib - Compilar el codigo de juego como `.so` / `.dll` y recargar al cambiar. - 0 KB extra runtime. - No funciona en WASM (no hay dylib loading dinamico). - No funciona en iOS (no se permite carga dinamica de codigo). - Solo util en desktop dev workflow. ### Opcion E — sin scripting + ccache + unity build - Compilar todo C++ con ccache. Cambios incrementales tipicos < 3s. - Unity build de la app reduce LTO time. - Hot reload de **assets y shaders** (que es lo que mas se itera) NO necesita scripting. ## Recomendacion previa Empezar con Opcion E. Solo si el dolor real aparece, evaluar A (wren) por ser la mas pequeña y compatible WASM. ## Si se aborda: scope minimo 1. Scripting solo en niveles altos (gameplay logic, AI scripts, dialogos). 2. Codigo "de motor" (rendering, physics, input) sigue en C++. 3. Bindings expuestos via funciones del registry (`script_register_*` para cada subsistema). 4. Hot reload de scripts en dev mode (file watcher). 5. Empaquetar scripts en el `.pak` de assets. ## Funciones (cuando llegue el momento) - `cpp/functions/gamedev/wren_vm.{cpp,h,md}` — VM lifecycle - `cpp/functions/gamedev/wren_bind.{cpp,h,md}` — registrar funciones C++ a wren - `cpp/functions/gamedev/wren_call.{cpp,h,md}` — invocar funciones wren desde C++ ## Tamaño objetivo si se hace - Wren: ~60 KB total (vm + bindings). - Bindings de juego: ~10 KB. - Maximo aceptable: 100 KB. ## Criterio para cerrar este issue - Decision tomada: si o no. - Si si: VM integrada, bindings minimos, demo de un script de AI cargado en runtime. - Si no: documentar el por qué en `cpp/GAMEDEV.md` (helpful no future contributors). ## No-objetivos - Visual scripting (Blueprints style). - Scripting para todo el juego. - Multiples lenguajes de scripting.