---
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.
