WENOPAL

04 · Texturas e íconos

Qué imagen busca el motor para íconos, modelos, ropa e interfaz, con qué nombre y formato, y cómo hacer variantes sin código.

Curso técnico · Build 42 · Actualizado el

Objetivo: saber qué imagen busca el motor en cada caso (ícono, modelo, ropa, interfaz), con qué nombre, tamaño y formato, y cómo hacer variantes (podrido, cocido, colores) sin escribir código.

1. Los cuatro tipos de imagen

TipoDónde vaNombreFormato típicoQuién la pide
Ícono de ítemmedia/textures/Item_<Icon>.png32×32, RGBA (con transparencia)Icon = <Icon> en el script del ítem
Textura de modelomedia/textures/ (o subcarpetas)libre512×512 o 256×256, RGBtexture = <nombre> en el model del script
Textura de ropamedia/textures/...libresegún el UV del cuerpoel .xml de la prenda (módulo 05)
Imagen de interfazmedia/ui/librecualquieraLua: getTexture("media/ui/...png")

Datos reales de los mods de Wenopal:

  • Tocomples Food, uno de nuestros mods: 161 texturas; los íconos son Item_*.png de 32×32 RGBA; las texturas de los modelos (VienesaBurnt.png, SopaipillasPebreRotten.png) son de 512×512 RGB.
  • Catimbas pone sus íconos en Contents/mods/Catimbas/common/media/textures/: la carpeta common/ funciona para assets.
  • Emote Bubbles carga sus cuadros de animación de media/ui/EmoteBubbles/<id>_<n>.png desde Lua.

2. Íconos: nombre y variantes por estado

Icon = CompletoItaliano → el motor busca la textura Item_CompletoItaliano. Sin el prefijo Item_ sale el ícono de signo de pregunta.

Para la comida, el motor busca variantes por sufijo, sin que las declares en el script:

EstadoÍcono que buscaEjemplo en Tocomples Food
normalItem_X.pngItem_BarrosJarpa.png
podridoItem_XRotten.pngItem_BarrosJarpaRotten.png
cocidoItem_XCooked.pngItem_HamburguesaCooked.png
quemadoItem_XBurnt.pngItem_HamburguesaBurnt.png

Lo mismo pasa con los modelos: el CompletoItaliano.txt de Tocomples Food define model CompletoItaliano y model CompletoItalianoRotten (con texture = CompletoItalianoRotten), y el juego elige el modelo podrido cuando corresponde.

3. Variantes sin texturas nuevas

Campo del ítemQué haceEjemplo del juego
IconsForTexture = A;B;CUn ícono distinto por cada variante de textura de una prenda (el índice calza con textureChoices del .xml)Glasses_Normal: GlassesBlack;GlassesBlue;GlassesRed
IconColorMask = XUna máscara que se pinta con el color del ítemLipstick: IconColorMask = Lipstick_Mask
IconFluidMask = XLo mismo, con el color del fluido que contienebotellas y baldes
ColorRed/Green/BlueTiñe el ítem131 ítems

Con IconColorMask haces un solo ícono gris + una máscara, y cada color sale gratis.

4. Las texturas del juego: .pack

Las texturas del juego base vienen en atlas empaquetados (media/texturepacks/*.pack), no como .png sueltos. Por eso no encuentras Item_Apple.png en ninguna carpeta.

Para ver una textura del juego sin desempaquetar nada: en modo debug, el visor de texturas (lua/client/DebugUIs/TextureViewer.lua). Desde la consola Lua también puedes pedirla por nombre: getTexture("Item_Apple") (el juego mismo hace getTexture("Item_TrapBox") en su Lua) devuelve el objeto si existe y nil si no. Para archivos sueltos se usa la ruta: getTexture("media/ui/TargetPos.png"). Eso sirve para comprobar si un nombre está bien escrito antes de usarlo.

Si quieres reutilizar una textura del juego en tu modelo, no la copies: refiérete a ella por nombre. Si la modificas, entonces sí va en tu mod con otro nombre.

5. Reglas que ahorran problemas

  • PNG siempre. El juego también lee otros formatos en algunos casos, pero todos nuestros mods usan PNG y funciona.
  • Potencias de 2 para texturas de modelos (256, 512, 1024): es lo que esperan las GPU y lo que usa el juego.
  • Íconos con transparencia real (canal alfa), no fondo blanco.
  • Nombres únicos con prefijo del mod (Catimbas_...): las texturas comparten un solo espacio de nombres con el juego y con todos los mods. Si dos mods traen Item_Pan.png, gana el último en cargar.
  • Caché: el juego no relee texturas en caliente. Cambiaste un PNG → reinicia el juego.

Ejercicios

Ejercicio 4.1 · Íconos con estados

Haz los íconos de la Sopaipilla (ejercicio 2.1): normal y podrida. Si haces que se pueda cocinar (IsCookable = true, MinutesToCook, MinutesToBurn), agrega también cocida y quemada.

Listo cuando: ves los cuatro íconos al pasar por cada estado (acelera el tiempo y usa una cocina).

Ejercicio 4.2 · ¿Existe esta textura?

En la consola Lua, escribe una función CursoLab.tex(nombre) que imprima si una textura existe y su tamaño (getWidth(), getHeight()). Úsala con Item_Apple, Item_Sopaipilla y un nombre que no exista.

Listo cuando: la función distingue los tres casos. Guárdala en CursoLab_Core.lua: la vas a usar para depurar.

Una solución
lua
function CursoLab.tex(name)
    local t = getTexture(name)
    if not t then
        CursoLab.log("NO existe:", name)
    else
        CursoLab.log(name, t:getWidth() .. "x" .. t:getHeight())
    end
    return t
end

Ejercicio 4.3 · Un ícono, muchos colores

Haz un ítem CursoLab.Pañuelo con un ícono gris y una máscara (IconColorMask), y tres variantes de color.

Listo cuando: los tres pañuelos se ven de colores distintos usando un solo par de PNG.

Ejercicio 4.4 · Pisar una textura (y deshacerlo)

  1. Pon en CursoLab un Item_Apple.png propio (una manzana azul).
  2. Comprueba qué ves en el juego. ¿Por qué funciona aunque la del juego esté dentro de un .pack?
  3. Bórralo y escribe en tus notas en qué casos un mod debería hacer esto a propósito.

Desafío 4

Escribe pzicons.py: recorre los scripts de un mod y avisa de cada Icon = X sin su Item_X.png, cada comida sin ícono Rotten, y cada PNG de textures/ que nadie usa. Pásalo por Tocomples Food y Catimbas.


Anterior: 03 · Recetas y entidades · Siguiente: 05 · Modelos 3D