WENOPAL

03 · Scripts: recetas y entidades (B42)

Escribe recetas craftRecipe de Build 42 compatibles con otros mods, controla cómo se aprenden y crea una estación de trabajo propia.

Curso técnico · Build 42 · Actualizado el

Objetivo: escribir recetas de B42 entendiendo cada parte del craftRecipe, hacer que convivan con los ítems de otros mods, y crear una estación de trabajo propia (una entity con CraftBench).

1. Anatomía de un craftRecipe

La receta del Completo Italiano de Tocomples Food, uno de nuestros mods (tomCompleItaliano/.../scripts/recipes/CompletoItaliano.txt):

craftRecipe MakeCompletoItaliano
{
    timedAction = Making,              ← animación y sonido mientras se fabrica
    time = 60,                         ← duración (ticks de la acción)
    Tags = InHandCraft;Cooking,        ← DÓNDE se puede hacer y en qué pestaña sale
    category = Cooking,                ← categoría en la ventana de crafteo
    xpAward = Cooking:3,               ← experiencia que da
    inputs
    {
        item 1 [CompleteItaliano.PanCompleto;Base.BunsHotdog_single] flags[InheritFoodAge;ItemCount],
        item 1 [CompleteItaliano.Vienesa;Base.Hotdog_single] flags[InheritFoodAge;ItemCount],
        item 1 [CompleteItaliano.Palta;Base.Avocado] flags[InheritFoodAge;ItemCount],
        item 1 [Base.Tomato] flags[InheritFoodAge;ItemCount],
        item 2 [Base.MayonnaiseFull],
    }
    outputs
    {
        item 1 CompleteItaliano.CompletoItaliano,
    }
}

Campos de la receta (contados en scripts/generated/recipes/)

CampoPara quéEjemplo
timedActionQué acción se reproduceMaking, SawLogs, BuildWallHammer
timeDuración60
TagsDónde se hace: InHandCraft (en la mano, 241 recetas), AnySurfaceCraft (sobre una superficie, 381), CanBeDoneFromFloor, CanBeDoneInDark; o el nombre de una estación (sección 4)Tags = AnySurfaceCraft;CanBeDoneFromFloor
categoryPestaña en la ventana de crafteoCarpentry, Cooking
xpAwardXP por habilidadWoodwork:5
SkillRequiredNivel mínimoMasonry:2 (297 recetas)
NeedToBeLearnHay que aprenderla (libro, revista, investigar)true
AutoLearnAny / AutoLearnAllSe aprende sola al llegar a un nivelAutoLearnAny = Maintenance:10
AllowBatchCraftPermite fabricar varias de una veztrue
OnCreate / OnTestCódigo que corre al terminar / para validarRecipeCodeOnCreate.minorCondition
MetaRecipeAgrupa variantes de la misma receta para aprenderlas juntasbase:makebonearmor

2. Las líneas de inputs y outputs

Formato general:

item <cantidad> <qué> [mode:...] [flags[...]] [mappers[...]]

Qué ítem acepta:

  • Lista explícita: [Base.Log] o [Base.Dogbane;Base.HempScutched] (cualquiera de la lista).
  • Por tag: tags[base:saw;base:crudesaw] → cualquier ítem con alguno de esos tags. Prefiere esto (módulo 02, sección 4).
  • Cantidad variable: item variable[1:20] [Base.Basil] (el secador de hierbas acepta de 1 a 20).

Qué le pasa al ítem (mode:):

ModoQué haceUsos en el juego
(sin modo)Se consumela mayoría
mode:keepSe usa pero no se gasta: es una herramienta1.502
mode:destroyEl ítem desaparece entero (ejercicio: lee 3 recetas del juego con mode:destroy y escribe en qué se diferencia de consumirlo)244
mode:mixturePara fluidos que se mezclan26

Flags más usados (con cuántas veces aparecen en el juego):

FlagQué hace
MayDegradeLight (1.016), MayDegradeVeryLight (170), MayDegrade (39)La herramienta puede perder condición al usarla
Prop1, Prop2Qué ítem se ve en la mano derecha / izquierda durante la animación
IsNotDull (219), SharpnessCheck (67)La herramienta tiene que tener filo
ItemCount (185)Cuenta unidades del ítem, no "usos"
DontRecordInput (104)No queda registrado en el resultado
InheritCondition (87), InheritFoodAge (46), InheritColor (34)El resultado hereda condición / frescura / color del ingrediente
NoBrokenItems (29)No acepta ítems rotos
IsEmpty, NotFullPara contenedores de líquido

Fluidos (agua, gasolina, tinte) no son ítems: van con -fluid:

-fluid 1.0 [Petrol],
-fluid 10.0 categories[Water] mode:mixture,

itemMapper: un resultado según el ingrediente

Cuando el resultado depende de qué entró (recipes_carpentry.txt, SawLongStick):

inputs  { item 1 [Base.LongStick;Base.Sapling] flags[Prop2;InheritCondition] mappers[StickMapper], ... }
outputs { item 2 mapper:StickMapper, }
itemMapper StickMapper
{
    Base.WoodenStick2 = Base.LongStick,     ← resultado = ingrediente
    Base.TreeBranch2 = Base.Sapling,
    default = Base.WoodenStick2,
}

3. Cómo se aprende una receta

Hay cuatro caminos, y conviene saber cuál usas antes de diseñar:

  1. Siempre conocida: sin NeedToBeLearn.
  2. Por lectura: el ítem (revista, libro) tiene LearnedRecipes = NombreReceta en su script.
  3. Investigando: un ítem con Researchablerecipes = NombreReceta; clic derecho → Investigar (así aprendes el encendedor improvisado del estropajo de acero).
  4. Por nivel: AutoLearnAny = Habilidad:N.

Tocomples Food usa el camino 2: RevistaCompletos tiene LearnedRecipes = MakeCompleto;MakeCompletoDinamico;... (14 recetas) y OnCreate = ItemCodeOnCreate.onCreateRecipeMagazine, igual que las revistas del juego.

4. Entidades y estaciones

En B42 los objetos que se construyen en el mundo (telares, hornos, paredes) son entity. Una entidad junta componentes:

entity SimpleLoom                         ← entities/agricultural/workstations/entity_simple_loom.txt
{
    component UiConfig     { xuiSkin = default, entityStyle = ES_SimpleLoom, uiEnabled = true, }
    component CraftBench   { Recipes = Weaving, }          ← es una estación: hace las recetas con Tags = Weaving
    component SpriteConfig { face S { layer { row = crafted_04_81, row = crafted_04_80, } } ... }
    component CraftRecipe  { ... inputs { item 1 tags[base:hammer] mode:keep ..., item 4 [Base.Log], ... } }
                             ↑ cómo se CONSTRUYE el telar
}

La conexión estación ↔ recetas es por nombre: CraftBench { Recipes = Weaving } y las recetas con Tags = Weaving (en entity_simple_loom_craftRecipe.txt). Estaciones del juego: WoodCharcoal, Weaving, PotteryWheel, DryingRackHerb, DryingRackGrain, TanLeather, Stone_Quern, SpinningWheel, Toaster...

SpriteConfig dice qué sprites del mapa (tiles) usa cada orientación: una entidad propia necesita tiles propios o reutilizar los del juego (los nombres como crafted_04_81 son tiles de los .pack de tiles).

5. ¿Dónde está el código de OnCreate?

Busca RecipeCodeOnCreate.minorCondition (31 recetas lo usan) en _juego/lua/. No vas a encontrar la definición: solo llamadas como RecipeCodeOnTest.cutFish(item, nil) en server/Fishing/. Eso significa que RecipeCodeOnCreate vive en Java y está expuesto a Lua. Es el primer caso del curso donde la respuesta no está en media/: en el módulo 08 lo abres en el .jar.


Ejercicios

Ejercicio 3.1 · Receta compatible

Receta CursoLab.HacerSopaipillas: harina + agua + aceite (o manteca) → 4 sopaipillas (las del ejercicio 2.1). Requisitos:

  • usa tags o listas que acepten variantes del juego (busca qué tags tienen la harina y el aceite),
  • necesita una superficie (no en la mano),
  • da XP de cocina,
  • las sopaipillas heredan la frescura de la harina.

Listo cuando: la receta sale en la ventana de crafteo con ingredientes del juego y el resultado tiene la frescura correcta.

Ejercicio 3.2 · Herramienta que se gasta

Haz que el DestornilladorChino del ejercicio 2.2 se desgaste rápido en tu receta pero normal en las del juego. ¿Dónde vive la decisión de desgaste: en el ítem o en la receta? Escríbelo en una frase.

Ejercicio 3.3 · Receta que hay que aprender

Crea una revista CursoLab.RevistaSopaipillas que enseñe la receta 3.1 y marca la receta con NeedToBeLearn = true.

Listo cuando: con un personaje nuevo la receta no aparece; después de leer la revista, sí.

Ejercicio 3.4 · Mapper

Receta "Rellenar": un pan (Base.Bread o el PanCompleto de Tocomples Food) + un relleno → un pan relleno distinto según el pan que usaste. Usa un itemMapper.

Ejercicio 3.5 · Una estación propia

Crea la entidad CursoLab.FreidoraSopaipillas:

  1. se construye con martillo + clavos + una olla, usando sprites del juego (busca un tile de cocina que sirva),
  2. tiene CraftBench { Recipes = CursoLabFreidora },
  3. la receta 3.1 pasa a hacerse solo en la freidora.

Listo cuando: construyes la freidora, haces clic derecho en ella y la receta aparece ahí y ya no en el inventario.

Desafío 3

Escribe pzrecipes.py: dado un ítem (Base.Log), lista todas las recetas que lo usan (directo o por tag) y las que lo producen, con el archivo y la línea. Es exactamente el cruce que hace la ficha por ítem del sitio (wenopal.work/referencia/items/): intenta hacerlo sin mirar, después compara.


Anterior: 02 · Scripts: ítems · Siguiente: 04 · Texturas e íconos