aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Metin2

Metin2 NPC-dialoog: vertakken met select en confirm

Een Metin2 NPC-dialoog begint op het moment dat een speler het gespreksvenster met een NPC opent, en als hij goed is opgebouwd voelt hij als een klein verhaal. Eén regel tekst tonen is makkelijk; het echte werk is de speler keuzes voorleggen en het gesprek vertakken op basis van de beslissing die hij neemt. In dit artikel loop ik stap voor stap door het bouwen van keuzemenu's met select, ja/nee-vensters met confirm, en hoe je ze combineert tot een nette, werkende Lua-quest.

Het basisgeraamte van een dialoog

Elk NPC-gesprek opent met een chat-trigger. Je schrijft de vnum van de NPC, geeft het venster een titel en zet de tekst regel voor regel neer met say-functies.

quest dorpeling_dialoog begin
    state start begin
        when 9003.chat."Praat met de dorpeling" begin
            say_title("Oude dorpeling")
            say("Welkom, reiziger.")
            say("")
            say("Wat brengt je hierheen?")
        end
    end
end

Hier is 9003 de vnum van de NPC, say_title de kop van het dialoogvenster en say de bodytekst. Een lege say("") wordt gebruikt om een witregel te laten. Dit blok is eenrichtingsverkeer: de speler leest alleen en klikt op "Sluiten". Om interactie toe te voegen hebben we de keuzemechanismen nodig.

Keuzemenu's met select

select toont de speler een lijst met knoppen en geeft de index van de gekozen optie terug (beginnend bij 1). Je vangt de teruggegeven waarde op in een variabele en vertakt erop met if / elseif.

when 9003.chat."Praat met de dorpeling" begin
    say_title("Oude dorpeling")
    say("Hoe kan ik je helpen?")
    say("")
    local keuze = select("Geef me een quest", "Goederen kopen", "Vertel je verhaal", "Laat maar")

    if keuze == 1 then
        say("Luister dan: ruim de wolven in het bos op.")
    elseif keuze == 2 then
        say("Helaas heb ik niets meer te verkopen.")
    elseif keuze == 3 then
        say("Jaren geleden was dit dorp heel anders...")
    else
        say("Goede reis.")
    end
end

Een paar aandachtspunten: in de praktijk is select comfortabel tot ongeveer 6-7 opties; meer en ze passen niet in het dialoogvenster. De laatste optie een "Laat maar"-uitgang maken is een goede gewoonte, zodat de speler nooit vastloopt in het menu. Bewaar de teruggegeven waarde altijd in een local variabele, want als je een tweede select aanroept, gaat de vorige waarde verloren.

Ja/nee-bevestiging met confirm

Vóór een onomkeerbare actie (een item verwijderen, teleporteren, yang uitgeven) wil je de speler om bevestiging vragen. confirm("tekst") is precies hiervoor bedoeld: het opent een "Ja / Nee"-venster voor de speler en geeft true terug als hij akkoord gaat en false als hij weigert.

when 9003.chat."Teleporteer naar de stad" begin
    say_title("Oude dorpeling")
    say("Zal ik je naar de stad sturen?")
    say("Dit kost 50.000 yang.")
    say("")

    if confirm("Wil je naar de stad teleporteren?") then
        if pc.get_money() >= 50000 then
            pc.change_money(-50000)
            pc.warp(469000, 964000)
        else
            say("Je hebt niet genoeg yang.")
        end
    else
        say("Misschien een andere keer.")
    end
end

confirm kan rechtstreeks binnen een if-voorwaarde worden gebruikt omdat het een boolean teruggeeft. Sommige versies bieden ook confirm_with_button("vraag", "Ja-label", "Nee-label") voor aangepaste knoptekst; maar omdat de beschikbaarheid afhangt van je source, blijf bij de standaard confirm als je draagbaar wilt blijven.

select en confirm aan elkaar koppelen

De echte kracht verschijnt wanneer je de twee nest. De speler kiest eerst uit een select-menu en bevestigt dan zijn definitieve beslissing met confirm op het kritieke moment. Hieronder een voorbeeld van een beloningskist-NPC:

when 9003.chat."Beloningskist" begin
    say_title("Mysterieuze kist")
    say("Kies een beloning van binnen, maar wees voorzichtig.")
    say("Er is geen weg terug nadat je hebt gekozen.")
    say("")
    local beloning = select("Zwaard", "Harnas", "Yang", "Later")

    if beloning == 4 then
        say("De kist sloot zich.")
        return
    end

    if not confirm("Weet je zeker van je keuze?") then
        say("Je twijfelde even bij de kist.")
        return
    end

    if beloning == 1 then
        pc.give_item2(11209, 1)
        say("Je hebt een scherp zwaard verdiend!")
    elseif beloning == 2 then
        pc.give_item2(11949, 1)
        say("Je hebt een stevig harnas verdiend!")
    elseif beloning == 3 then
        pc.change_money(500000)
        say("Je hebt 500.000 yang verdiend!")
    end
end

Drie technieken werken hier samen: select bepaalt de tak, een vroege return handelt het "later"-geval netjes af, en confirm plaatst een laatste veiligheidspoort voordat de onomkeerbare beloning wordt uitgedeeld. return gebruiken houdt de code weg uit diepe if-nesting en goed leesbaar.

Tekst dynamisch maken

Statische tekst wordt snel saai. Om de naam van de speler, zijn level of het aantal items in de tekst te weven, gebruik je stringconcatenatie binnen say. In Lua is de concatenatie-operator twee punten (..).

when 9003.chat."Begroeten" begin
    say_title("Oude dorpeling")
    say("Hallo "..pc.get_name()..", goed je te zien.")
    say("Je bent level "..pc.get_level()..", je bent snel gevorderd.")
end

Hierdoor voelt dezelfde dialoog persoonlijk voor elke speler. Wanneer je numerieke waarden (pc.get_level()) in tekst mengt, converteert Lua ze automatisch, zodat je niet eens tostring() hoeft aan te roepen.

Veelgemaakte fouten en tips

  • Vergeten het select-resultaat te controleren: de speler kan het venster met ESC sluiten; definieer een tak voor elke optie plus een "laat maar"-uitgang.
  • confirm als een gewone if schrijven en de haakjes vergeten: confirm(...) heeft altijd een tekstargument nodig, laat het niet leeg.
  • Te lange say-ketens: toon de speler na 4-5 regels een "Doorgaan"-knop met wait(); anders loopt het tekstvenster over.
  • Speciale tekens: sla questbestanden op in de codering die de server verwacht (meestal UTF-8 of de relevante locale); een verkeerde codering verschijnt als onleesbare tekens in de dialoog.
  • Vergeet niet de quest na een wijziging te compileren en opnieuw te laden; anders blijft de game core de oude tekst tonen.

Veelgestelde vragen

Hoeveel opties ondersteunt select?

Er is geen harde technische limiet, maar in de praktijk passen 6-7 opties comfortabel in het dialoogvenster. Heb je er meer nodig, splits de opties dan in categorieën: toon de groepen in het eerste menu en open daarna een tweede select op basis van de gekozen groep. Dit oogt netter en blijft leesbaar.

Kan ik de knoptekst in het confirm-venster wijzigen?

De standaard confirm gebruikt vaste "Ja/Nee"-knoppen. Sommige sources bevatten een uitgebreide versie waarmee je aangepaste knoptekst kunt instellen, maar dat hangt af van je versie. Wil je draagbaarheid, dan is de veiligste weg de eigenlijke vraag duidelijk met say te formuleren en confirm simpel te houden.

Kan ik het select-resultaat rechtstreeks binnen een if gebruiken?

Dat kan, maar het wordt niet aangeraden. select toont het menu en geeft de waarde terug; als je dezelfde aanroep in twee if-takken herhaalt, opent het menu twee keer. Vang het resultaat liever op in een local variabele en vergelijk dan die variabele.

Vastgelopen op NPC-dialogen? Heb je hulp nodig bij vertakkende questketens, dialoogsystemen met meerdere stappen of menu-ontwerp voor je server, neem dan contact met me op — laten we het samen bouwen.

Bu kategorideki tüm yazılar →

Devamı için