WENOPAL

Cómo hacer tu primer mod de Project Zomboid (B42)

Hacemos un mod completo desde cero: una sopaipilla que se come y aparece en los refrigeradores. Estructura, mod.info, ítem, ícono, traducción y loot.

Nivel básico · Actualizada el

Vamos a hacer un mod chico pero completo: una sopaipilla que se puede comer, con su ícono y su nombre en español e inglés, y que aparece en los refrigeradores del mapa. Es la misma receta que usamos en mods reales como Melón con Vino, así que lo que aprendas aquí sirve de verdad.

1. La estructura de carpetas

Dentro de tu carpeta Zomboid/Workshop/ crea esto (los nombres importan, incluso mayúsculas y minúsculas):

text
Zomboid/Workshop/
└── Sopaipillas/                      <- la carpeta del proyecto
    ├── workshop.txt                  <- datos para Steam (paso 7)
    ├── preview.png                   <- imagen del Workshop
    └── Contents/
        └── mods/
            └── Sopaipillas/          <- el ID del mod
                └── 42/               <- archivos para Build 42
                    ├── mod.info
                    └── media/
                        ├── scripts/items/Sopaipillas.txt
                        ├── textures/Item_Sopaipilla.png
                        └── lua/
                            ├── server/Items/SopaipillasLoot.lua
                            └── shared/Translate/
                                ├── ES/ItemName.json
                                └── EN/ItemName.json

La carpeta 42/ le dice al juego que esos archivos son para Build 42. Algunos mods tienen también una carpeta common/ para archivos que sirven en cualquier versión, pero no es obligatoria: nuestro mod Terremoto funciona sin ella.

2. mod.info: la ficha del mod

ini
name=Sopaipillas
id=Sopaipillas
description=Sopaipillas para comer en el apocalipsis. Build 42.
author=TuNombre
modversion=1.0.0
versionMin=42.0.0
  • id tiene que ser único y igual al nombre de la carpeta que está dentro de mods/.
  • versionMin es la versión mínima del juego que necesita tu mod.
  • Puedes agregar poster=poster.png e icon=icon.png (dentro de 42/) para que se vea bonito en el menú de mods.

3. El ítem

media/scripts/items/Sopaipillas.txt:

text
module Sopaipillas
{
    imports
    {
        Base,
    }

    item Sopaipilla
    {
        DisplayName = Sopaipilla,
        DisplayCategory = Food,
        ItemType = base:food,
        Icon = Sopaipilla,
        Weight = 0.1,
        HungerChange = -12,
        UnhappyChange = -5,
        DaysFresh = 3,
        DaysTotallyRotten = 6,
        Calories = 250,
        Carbohydrates = 30,
        Lipids = 12,
        Proteins = 4,
    }
}

Qué significa cada parte:

  • module Sopaipillas es el apellido de tus ítems. Este se llamará Sopaipillas.Sopaipilla en todo el juego. Usa un nombre propio y corto para no chocar con otros mods.
  • ItemType = base:food lo hace comida. Para un objeto cualquiera usa base:normal.
  • Icon = Sopaipilla busca la imagen textures/Item_Sopaipilla.png. El juego le agrega Item_ adelante solo.
  • HungerChange negativo quita hambre. UnhappyChange negativo sube el ánimo.
  • DaysFresh y DaysTotallyRotten controlan cuándo se pone vieja y cuándo se pudre.

4. El ícono

Dibuja un PNG de 32×32 píxeles con fondo transparente y guárdalo como media/textures/Item_Sopaipilla.png. Si no le pones modelo 3D, el juego también usa este ícono para mostrar el ítem tirado en el suelo.

5. El nombre en cada idioma

Desde Build 42 las traducciones son archivos JSON. media/lua/shared/Translate/ES/ItemName.json:

json
{
    "Sopaipillas.Sopaipilla": "Sopaipilla"
}

Y EN/ItemName.json:

json
{
    "Sopaipillas.Sopaipilla": "Sopaipilla (fried dough)"
}

La clave es siempre Modulo.Item. Más detalles en Traducciones en B42.

6. Que aparezca en el mundo (loot)

media/lua/server/Items/SopaipillasLoot.lua:

lua
require "Items/ProceduralDistributions"

local function agregarLoot()
    local ok, err = pcall(function()
        local function meter(lista, peso)
            local dist = ProceduralDistributions.list[lista]
            if not dist or not dist.items then return end   -- si la lista no existe, no rompemos nada
            table.insert(dist.items, "Sopaipillas.Sopaipilla")
            table.insert(dist.items, peso)
        end
        meter("FridgeGeneric", 2)
        meter("FridgeTrailerPark", 3)
        meter("FridgeBreakRoom", 1)
    end)
    if not ok then print("[Sopaipillas] error en el loot: " .. tostring(err)) end
end

Events.OnPostDistributionMerge.Add(agregarLoot)

Cada contenedor del mapa tiene una lista de loot con pares de ítem y peso. Aquí agregamos la sopaipilla a tres listas de refrigeradores. Todo va dentro de pcall para que, si algo falla, el mod no tire abajo la carga del juego. Explicación completa en Loot.

7. Probarlo en el juego

  1. Abre el juego con -debug (ver la guía anterior).
  2. En Mods, activa "Sopaipillas".
  3. Empieza una partida nueva.
  4. En el menú debug abre Items List, busca "Sopaipilla" y agrégala al inventario.
  5. Revisa que tenga ícono y nombre, y cómetela.
  6. Si algo no aparece, abre Zomboid/console.txt y busca "Sopaipillas" o "ERROR".

8. workshop.txt y publicar

ini
version=1
title=Sopaipillas [B42]
description=Sopaipillas para comer en el apocalipsis.
tags=Build 42;Food
visibility=public

Pon también un preview.png en la carpeta del proyecto (cuadrado, menos de 1 MB). Después se sube desde el juego: Publicar en el Workshop.

¿Y ahora?