Level 2–3 – Items, Materialien & Crafting

Items, Materialien und Crafting verstehen

In Luanti besteht fast jede Mod aus drei Bausteinen: Gegenstände, Regeln und Verhalten. Gegenstände sind zum Beispiel Rohstoffe, Werkzeuge oder platzierbare Blöcke. Regeln sind Crafting-Rezepte. Verhalten steckt in Callbacks wie on_use. Wenn du diese drei Dinge verstehst, kannst du bereits kleine Produktionsketten, Werkzeuge und spielbare Ideen bauen.

Didaktik-Hinweis

Erkläre das Thema wie eine Werkstatt: Rohstoff → Zwischenprodukt → Werkzeug oder Endprodukt. So wird schnell klar, warum Items registriert werden, warum Rezepte Regeln sind und warum ein Werkzeug mehr ist als nur ein Bild im Inventar.

1. Was ist was? Node, Craftitem, Tool und Rezept

Begriff Registrierung Wofür? Merksatz
Node core.register_node Block oder Objekt in der Welt Kann in die Welt gesetzt werden.
Craftitem core.register_craftitem Material, Nahrung, Bauteil, Beute Lebt meist im Inventar.
Tool core.register_tool Werkzeug oder Waffe mit Verschleiß Hat Fähigkeiten und nutzt sich ab.
Rezept core.register_craft Regel, die Eingaben in Ausgaben umwandelt Ist kein Item, sondern eine Spielregel.

Der häufigste Denkfehler am Anfang: Ein Rezept ist kein Gegenstand. Es liegt nicht im Inventar. Es sagt dem Spiel nur: „Wenn diese Zutaten auftauchen, dann entsteht dieses Ergebnis.“

Merksatz

Ein Node baut die Welt, ein Craftitem wartet im Inventar, ein Tool arbeitet, und ein Rezept beschreibt eine Umwandlung.

2. Eindeutige Namen und wichtige Felder

Jedes Item braucht einen eindeutigen Namen im Muster modname:itemname. Dadurch können zwei Mods beide ein „Schwert“ besitzen, ohne sich gegenseitig zu überschreiben. Zusätzlich bekommt jedes Item eine Definitionstabelle mit Eigenschaften wie Beschreibung, Bild, Gruppen oder Verhalten.

Craftitem mit sauberem Namen und klaren Feldern
core.register_craftitem("school_materials:kristallsplitter", {
    -- description ist der sichtbare Name im Inventar.
    description = "Kristallsplitter",

    -- inventory_image bestimmt das Icon im Inventar und in Listen.
    inventory_image = "school_kristallsplitter.png",

    -- stack_max begrenzt, wie viele Exemplare in einen Stapel passen.
    stack_max = 99,

    -- groups macht das Item für Rezepte und Spielregeln auffindbar.
    groups = {crystal = 1, magic = 1},
})
Feld Bedeutung Typisch für
description Name, den Spielende im Inventar sehen Alle Items
inventory_image 2D-Bild für Inventar und HUD Craftitems und Tools
groups Ordnet ein Item in „Familien“ ein Nodes, Craftitems, Tools
stack_max Maximale Stapelgröße Vor allem Craftitems
on_use Aktion beim Benutzen des Items Interaktive Items
tool_capabilities Abbau, Schaden, Haltbarkeit Tools

3. Craftitems und Tools: Inventarbild vs. Verhalten

Ein Craftitem ist oft Material oder Nahrung. Ein Tool sieht auf den ersten Blick ähnlich aus, ist aber technisch spannender: Es besitzt Fähigkeiten, passt zu bestimmten Materialgruppen und nutzt sich ab.

Craftitem: Material und Nahrung
core.register_craftitem("school_materials:copper_ingot", {
    -- Ein einfacher Barren: gut als Zutat für weitere Rezepte.
    description = "Kupferbarren",
    inventory_image = "school_copper_ingot.png",
    groups = {metal = 1},
})

core.register_craftitem("school_materials:field_ration", {
    description = "Feldration",
    inventory_image = "school_ration.png",

    -- core.item_eat(4) stellt 4 Hungerpunkte wieder her.
    on_use = core.item_eat(4),

    -- Das Item ist Nahrung und kann zusätzlich als brennbares Material gelten.
    groups = {food = 1, flammable = 1},
})
Tool: Fähigkeiten statt nur Inventarbild
core.register_tool("school_materials:lehrlingshammer", {
    description = "Lehrlingshammer",
    inventory_image = "school_lehrlingshammer.png",

    tool_capabilities = {
        -- full_punch_interval steuert das Tempo zwischen zwei Schlägen.
        full_punch_interval = 1.1,

        -- max_drop_level beeinflusst, welche härteren Blöcke noch Beute abwerfen.
        max_drop_level = 1,

        groupcaps = {
            -- cracky steht typischerweise für Stein, Erz und ähnliche Materialien.
            cracky = {
                -- times enthält die Abbauzeit für verschiedene Härtestufen.
                times = {[1] = 3.8, [2] = 2.0, [3] = 1.0},

                -- uses ist grob die Anzahl sinnvoller Einsätze vor starkem Verschleiß.
                uses = 20,

                -- maxlevel begrenzt, wie harte Materialien das Tool noch schafft.
                maxlevel = 1,
            },
        },

        -- damage_groups betrifft Treffer auf Wesen, nicht das Abbauen von Nodes.
        damage_groups = {fleshy = 3},
    },
})

Typische Dig-Gruppen sind cracky, choppy, snappy, crumbly und oddly_breakable_by_hand. Ein Werkzeug ist nicht „einfach gut“, sondern gut für bestimmte Gruppen.

4. Crafting-Typen im Überblick

Typ Wann nutzen? Wichtige Felder
Shaped Wenn die Anordnung im Raster wichtig ist output, recipe
Shapeless Wenn nur Zutaten und Menge zählen type = "shapeless", recipe
Cooking Wenn ein Ofen oder eine Schmelze arbeitet type = "cooking", recipe, cooktime
Fuel Wenn ein Item als Brennstoff dienen soll type = "fuel", recipe, burntime
Replacements Wenn beim Crafting ein Restobjekt zurückkommen soll replacements innerhalb des Rezepts

Shaped ist der Standard. Wenn du kein type angibst, behandelt Luanti das Rezept bereits als geformtes Rezept mit festem Muster.

5. Shaped und Shapeless: Muster oder Mischung?

Erkläre das Raster am besten wie kariertes Papier: In jedem Feld liegt etwas oder es bleibt leer. Bei shaped muss das Bild genau stimmen. Bei shapeless zählt nur, dass die richtigen Zutaten vorhanden sind.

Shaped-Rezept: Form ist wichtig
core.register_craft({
    -- Kein type nötig: shaped ist die Standardform.
    output = "school_materials:kristallstab",

    recipe = {
        -- Leere Strings markieren freie Felder im Raster.
        {"", "school_materials:kristallsplitter", ""},

        -- In der Mitte steckt hier ein vorhandener Stock aus dem Spiel.
        {"", "default:stick", ""},

        -- Nur dieses genaue Muster ergibt den Kristallstab.
        {"", "school_materials:kristallsplitter", ""},
    },
})
Shapeless-Rezept: Nur die Zutaten zählen
core.register_craft({
    type = "shapeless",

    -- Drei Splitter ergeben hier drei Portionen Kristallstaub.
    output = "school_materials:kristallstaub 3",

    recipe = {
        -- Die Reihenfolge im Crafting-Feld spielt jetzt keine Rolle.
        "school_materials:kristallsplitter",
        "school_materials:kristallsplitter",
        "school_materials:kristallsplitter",
    },
})

6. Cooking, Fuel und Replacements

Manche Herstellungsprozesse sind keine Handarbeit, sondern laufen über einen Ofen. Zusätzlich kann ein Rezept leere Behälter oder andere Reste zurückgeben.

Ofen, Brennstoff und Rückgabe leerer Behälter
core.register_craft({
    type = "cooking",

    -- Aus Staub wird im Ofen ein härteres Zwischenprodukt.
    output = "school_materials:gehaerteter_kristall",
    recipe = "school_materials:kristallstaub",

    -- cooktime gibt an, wie lange der Ofen daran arbeitet.
    cooktime = 8,
})

core.register_craft({
    type = "fuel",

    -- Dieses Item darf als Brennstoff in den Ofen gelegt werden.
    recipe = "school_materials:holzspan",

    -- burntime ist die Brenndauer in Spielzeit-Einheiten.
    burntime = 5,
})

core.register_craft({
    output = "school_materials:glitzertrank",
    recipe = {
        {"school_materials:magisches_wasser", "school_materials:kristallstaub"},
    },

    -- replacements gibt Behälter oder Werkzeuge nach dem Craften zurück.
    replacements = {
        {"school_materials:magisches_wasser", "school_materials:leere_flasche"},
    },
})

7. Gruppen: Familien von Gegenständen

Gruppen sind wie Schubladen mit Etiketten. Ein Item kann gleichzeitig in mehreren Gruppen liegen, zum Beispiel wood, choppy und flammable. So kann das Spiel fragen: „Ist das irgendein Holz?“ statt „Ist das genau dieser eine Block?“

Warum das wichtig ist

Gruppen sind ein früher Einstieg in Abstraktion. Das Rezept kennt dann nicht nur ein einziges Item, sondern eine ganze Familie von passenden Items.

Gruppen definieren und in Rezepten verwenden
core.register_node("school_materials:zauberholz", {
    description = "Zauberholz",
    tiles = {"school_zauberholz.png"},

    -- Der Block gehört zu mehreren Gruppen gleichzeitig.
    groups = {choppy = 2, wood = 1, flammable = 2},
})

core.register_craft({
    output = "school_materials:holzgriff",
    recipe = {
        -- group:wood akzeptiert jedes Item mit groups = {wood = 1}.
        {"group:wood"},
        {"group:wood"},
    },
})

Wichtig: Der Wert wood = 1 bedeutet nicht „ein bisschen Holz“. Er markiert nur die Zugehörigkeit zur Gruppe wood.

8. ItemStacks und Items mit Verhalten

Im Inventar liegt intern nicht einfach ein Bild, sondern ein ItemStack. Ein Stack speichert Name, Anzahl, Verschleiß und weitere Daten. Dieses Modell brauchst du später für Truhen, Belohnungen, Maschinen und eigene Interaktionen.

ItemStacks: Was wirklich im Inventar gespeichert wird
local einzelner_splitter = ItemStack("school_materials:kristallsplitter")

local zehn_splitter = ItemStack("school_materials:kristallsplitter 10")

local genauer_stack = ItemStack({
    -- name ist das registrierte Item.
    name = "school_materials:kristallstaub",

    -- count ist die Anzahl im Stapel.
    count = 5,

    -- wear wäre vor allem bei Tools relevant.
    wear = 0,
})
Craftitem mit eigenem Verhalten über on_use
core.register_craftitem("school_materials:zauberapfel", {
    description = "Zauberapfel",
    inventory_image = "school_zauberapfel.png",

    on_use = function(itemstack, user, pointed_thing)
        -- Prüfen, ob wirklich ein Spieler das Item benutzt hat.
        if user then
            core.chat_send_player(user:get_player_name(), "Du fühlst magische Energie!")
        end

        -- Genau ein Exemplar aus dem Stack verbrauchen.
        itemstack:take_item()

        -- Der aktualisierte Stack muss zurückgegeben werden.
        return itemstack
    end,
})

Spätestens hier wird klar: Ein Gegenstand ist nicht nur ein Icon, sondern kann ein kleines Programm sein.

9. Mini-Projekt: Die Kristallwerkstatt

Dieses Beispiel verbindet mehrere Ideen zu einer kleinen Produktionskette: Rohstoff → Zwischenprodukt → Ofenprodukt → fertiges Magie-Item.

Zusammenhängendes Beispiel für eine kleine Materialkette
core.register_craftitem("school_materials:kristallsplitter", {
    -- Rohstoff, den Spielende finden oder als Beute erhalten.
    description = "Kristallsplitter",
    inventory_image = "school_kristallsplitter.png",
})

core.register_craftitem("school_materials:kristallstaub", {
    -- Zwischenprodukt: entsteht erst durch ein Rezept.
    description = "Kristallstaub",
    inventory_image = "school_kristallstaub.png",
})

core.register_craftitem("school_materials:gehaerteter_kristall", {
    -- Zweites Zwischenprodukt: muss im Ofen verarbeitet werden.
    description = "Gehärteter Kristall",
    inventory_image = "school_gehaerteter_kristall.png",
})

core.register_craftitem("school_materials:zauberstab", {
    description = "Zauberstab",
    inventory_image = "school_zauberstab.png",

    on_use = function(itemstack, user, pointed_thing)
        -- Das Endprodukt darf beim Benutzen eine sichtbare Reaktion auslösen.
        if user then
            core.chat_send_player(user:get_player_name(), "Der Zauberstab funkelt hell!")
        end

        -- Der Stab wird hier nicht verbraucht, deshalb unverändert zurückgeben.
        return itemstack
    end,
})

core.register_craft({
    type = "shapeless",
    output = "school_materials:kristallstaub 2",
    recipe = {
        -- Drei Rohstoffe werden zu feinem Material zermahlen.
        "school_materials:kristallsplitter",
        "school_materials:kristallsplitter",
        "school_materials:kristallsplitter",
    },
})

core.register_craft({
    type = "cooking",
    output = "school_materials:gehaerteter_kristall",
    recipe = "school_materials:kristallstaub",
    cooktime = 6,
})

core.register_craft({
    output = "school_materials:zauberstab",
    recipe = {
        -- Oben steckt der wertvolle Kristallkern.
        {"", "school_materials:gehaerteter_kristall", ""},

        -- Unten bildet ein einfacher Stock den Griff.
        {"", "default:stick", ""},
        {"", "default:stick", ""},
    },
})

Dieses Mini-Projekt ist didaktisch stark, weil es nicht nur einzelne API-Aufrufe zeigt, sondern eine echte Produktkette mit verständlichen Rollen.

10. Typische Fehler und wie man sie vermeidet

11. Mini-Aufgaben für Unterricht oder Selbstlernen

  1. Erstelle einen Rohstoff, ein Zwischenprodukt und ein Endprodukt mit einer kleinen Crafting-Kette.
  2. Baue ein Werkzeug mit tool_capabilities und teste es an einem Node mit passender Gruppe.
  3. Lege ein shapeless Rezept an, bei dem drei Materialien zu einem Staub oder Mix werden.
  4. Füge ein Fuel-Rezept hinzu und vergleiche verschiedene burntime-Werte.
  5. Erweitere ein Rezept um replacements, damit eine leere Flasche oder Form zurückkommt.

12. Wie testen?

13. Weiterführende Seiten