WENOPAL

00 · Entorno de trabajo

Arma un ciclo rápido para modear Project Zomboid con las carpetas clave, modo debug, logs, VS Code y recarga de Lua sin reiniciar.

Curso técnico · Build 42 · Actualizado el

Objetivo: tener un ciclo de trabajo rápido (editar → ver el resultado en segundos) y saber dónde mirar cuando algo pasa. Todo lo demás del curso se apoya en esto.

1. Las tres carpetas que importan (Mac)

CarpetaQué hayPara qué la usas
~/Library/Application Support/Steam/steamapps/common/ProjectZomboid/Project Zomboid.app/Contents/Java/El juego: projectzomboid.jar (el motor en Java) y media/ (scripts, Lua, texturas, modelos)Solo lectura. Es la "documentación" real del juego
~/Zomboid/Todo lo del usuario: console.txt, Logs/, Saves/, Workshop/, mods/, Lua/Logs, partidas de prueba, archivos que escriben los mods
~/Zomboid/Workshop/<Mod>/Cada mod, con la forma que espera SteamDonde trabajas

La forma de un mod en Build 42

~/Zomboid/Workshop/CursoLab/
├── preview.png                      ← imagen de Steam (256×256)
├── workshop.txt                     ← datos de la página de Steam (lo llena el uploader)
└── Contents/mods/CursoLab/
    ├── common/                      ← (opcional) assets que sirven para cualquier versión
    └── 42/                          ← lo que carga Build 42
        ├── mod.info
        ├── poster.png
        └── media/
            ├── lua/{shared,client,server}/
            ├── scripts/
            └── textures/

mod.info mínimo (copiado de Emote Bubbles, uno de nuestros mods):

ini
name=Curso Lab
id=CursoLab
description=Mod de práctica del curso.
poster=poster.png
versionMin=42.0.0
author=elp4nsho
modversion=0.1.0

id tiene que ser igual al nombre de la carpeta dentro de Contents/mods/. Es el error número uno cuando un mod "no aparece".

2. Modo debug

En Steam: clic derecho en Project Zomboid → Propiedades → Opciones de lanzamiento → -debug.

Qué te da (sacado de media/lua/shared/keyBinding.lua, sección [Debug]):

TeclaQué hace
F11Lua debugger: lista de archivos Lua cargados, botón Reload, breakpoints, inspector de objetos
` `` (tecla a la izquierda del 1)Consola Lua: ejecuta Lua en vivo dentro del juego
Íconos a la izquierda de la pantallaMenú debug: teletransporte, spawnear ítems y vehículos, horda, clima, ver loot

Los errores de Lua aparecen en pantalla (contador rojo abajo a la derecha) apenas ocurren. En el modo normal pasan en silencio y solo quedan en el log.

3. Logs

  • ~/Zomboid/console.txt: el log de la sesión actual. Se reescribe cada vez que abres el juego.
  • ~/Zomboid/Logs/: una carpeta por sesión con logs más completos (*_DebugLog.txt). Si el juego se cae cargando, el error de verdad suele estar aquí.

Ten console.txt siempre abierto en una terminal:

sh
tail -f ~/Zomboid/console.txt | grep --line-buffered -E "CursoLab|ERROR|Exception|STACK"

4. VS Code que entienda el juego

  1. Instala la extensión Lua (sumneko / LuaLS).
  2. En la configuración del workspace donde trabajas (.vscode/settings.json):
json
{
  "Lua.runtime.version": "Lua 5.1",
  "Lua.workspace.library": ["~/Zomboid/Workshop/_juego/lua"],
  "Lua.diagnostics.globals": ["Events", "getPlayer", "getText", "ISContextMenu", "ISBaseTimedAction"]
}

Con _juego/lua como librería, Ir a la definición (F12) sobre ISBaseTimedAction te lleva al código del juego. Las funciones que vienen de Java (como getPlayer()) no tienen código Lua: esas se ven en el módulo 07.

5. El ciclo rápido

Cambiaste…Para verlo
Un .lua de client/ o shared/F11 → busca el archivo → Reload. Ojo: vuelve a correr el archivo completo, así que los Events.X.Add(...) se registran dos veces (lo arreglamos en el ejercicio 3)
Un .lua de server/ en una partida localIgual que arriba
Un script .txt (ítems, recetas, modelos)Salir al menú y volver a cargar la partida. Si no basta, reiniciar el juego
Una textura o un modeloReiniciar el juego (las texturas quedan en caché)
mod.infoReiniciar el juego

Ten una partida de pruebas dedicada: modo sandbox, sin zombis, con el mod activado. Así cargas en segundos.


Ejercicios

Ejercicio 0.1 · CursoLab existe

Crea el mod CursoLab con la estructura de arriba y este archivo:

42/media/lua/shared/CursoLab_Core.lua

lua
CursoLab = CursoLab or {}
CursoLab.VERSION = "0.1.0"

function CursoLab.log(...)
    local parts = {}
    for i = 1, select("#", ...) do
        parts[#parts + 1] = tostring(select(i, ...))
    end
    print("[CursoLab] " .. table.concat(parts, " "))
end

CursoLab.log("archivo cargado")
Events.OnGameStart.Add(function() CursoLab.log("OnGameStart") end)

Listo cuando: el mod aparece en la lista de mods, y en console.txt ves [CursoLab] archivo cargado y, al entrar a la partida, [CursoLab] OnGameStart.

Pregunta: ¿el primer mensaje sale antes o después del menú principal? ¿Por qué? (Pista: ¿cuándo se cargan los archivos de shared/?)

Ejercicio 0.2 · La consola Lua

En una partida con -debug, abre la consola (` ``) y ejecuta:

lua
CursoLab.log("hola desde la consola")
print(getPlayer():getFullName())
print(getPlayer():getX(), getPlayer():getY(), getPlayer():getZ())

Listo cuando: ves tu nombre y tus coordenadas. Acabas de llamar a métodos Java de un objeto IsoPlayer desde Lua. En el módulo 07 vemos cómo funciona eso por dentro.

Ejercicio 0.3 · Recargar sin duplicar

  1. Cambia el mensaje de OnGameStart y recarga el archivo con F11 → Reload.
  2. Agrega un Events.EveryOneMinute.Add(...) que escriba un mensaje. Recarga dos veces. ¿Cuántas veces sale el mensaje por minuto?
  3. Arréglalo para que recargar no duplique el handler.

Listo cuando: puedes recargar el archivo diez veces y el mensaje sale una vez por minuto.

Una solución
lua
if CursoLab.onMinute then
    Events.EveryOneMinute.Remove(CursoLab.onMinute)
end
function CursoLab.onMinute()
    CursoLab.log("pasó un minuto")
end
Events.EveryOneMinute.Add(CursoLab.onMinute)

Events.X.Remove necesita la misma función que pasaste a Add. Por eso guardamos la referencia en la tabla del mod, que sobrevive a la recarga. Con una función anónima no hay cómo sacarla.

Desafío 0

Haz un script de shell lab.sh que:

  1. copie un .lua que editaste a la carpeta del mod (si trabajas en otra carpeta), y
  2. muestre solo las líneas nuevas de console.txt que contengan CursoLab o un error, con color.

No hay solución: es tu herramienta, hazla a tu gusto.


Siguiente: 01 · Anatomía del juego y de un mod