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
| Tipo | Dónde va | Nombre | Formato típico | Quién la pide |
|---|---|---|---|---|
| Ícono de ítem | media/textures/ | Item_<Icon>.png | 32×32, RGBA (con transparencia) | Icon = <Icon> en el script del ítem |
| Textura de modelo | media/textures/ (o subcarpetas) | libre | 512×512 o 256×256, RGB | texture = <nombre> en el model del script |
| Textura de ropa | media/textures/... | libre | según el UV del cuerpo | el .xml de la prenda (módulo 05) |
| Imagen de interfaz | media/ui/ | libre | cualquiera | Lua: getTexture("media/ui/...png") |
Datos reales de los mods de Wenopal:
- Tocomples Food, uno de nuestros mods: 161 texturas; los íconos son
Item_*.pngde 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 carpetacommon/funciona para assets. - Emote Bubbles carga sus cuadros de animación de
media/ui/EmoteBubbles/<id>_<n>.pngdesde 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 busca | Ejemplo en Tocomples Food |
|---|---|---|
| normal | Item_X.png | Item_BarrosJarpa.png |
| podrido | Item_XRotten.png | Item_BarrosJarpaRotten.png |
| cocido | Item_XCooked.png | Item_HamburguesaCooked.png |
| quemado | Item_XBurnt.png | Item_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 ítem | Qué hace | Ejemplo del juego |
|---|---|---|
IconsForTexture = A;B;C | Un ícono distinto por cada variante de textura de una prenda (el índice calza con textureChoices del .xml) | Glasses_Normal: GlassesBlack;GlassesBlue;GlassesRed |
IconColorMask = X | Una máscara que se pinta con el color del ítem | Lipstick: IconColorMask = Lipstick_Mask |
IconFluidMask = X | Lo mismo, con el color del fluido que contiene | botellas y baldes |
ColorRed/Green/Blue | Tiñe el ítem | 131 í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 traenItem_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
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
endEjercicio 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)
- Pon en CursoLab un
Item_Apple.pngpropio (una manzana azul). - Comprueba qué ves en el juego. ¿Por qué funciona aunque la del juego esté dentro de un
.pack? - 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