Menu structure

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Bindie
Party member
Posts: 151
Joined: Fri Jan 23, 2015 1:29 pm

Menu structure

Post by Bindie »

Hey, what would be the best way of structuring a npc dialogue menu tree?
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Menu structure

Post by s-ol »

Bindie, there is no way anyone could realistically provide an adequate response.
This question is so broad, there is just no answer. There are million of "right" ways, and it completely depends on what you want to achieve, what you already have, how your game/engine works, how the things are supposed to work together, whether the plot is predefined or supposed to be generated, etc...

There are libraries that can take weight of your shoulders and do most things for you, and you're just a forum search away.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Menu structure

Post by Jasoco »

I'd be interested in knowing a few ways to deal with and store this kind of scripting system.

I mean it's easy to just make a linear script that ends with a choice that then loads another script depending on the choice. But how would you go about storing, and traversing a tree with all the choices as separate branches.
User avatar
Kingdaro
Party member
Posts: 395
Joined: Sun Jul 18, 2010 3:08 am

Re: Menu structure

Post by Kingdaro »

Like others have said, there's no best way of doing it, and generally, if you're going to actually make a scripted system for it, chances are, no matter how you do it, it's gonna get pretty nesty. This is one solution I've come up with:

Code: Select all

shopkeeperDialogue = {
  text = "Hello! How may I help you?",
  choices = {
    {
      text = "Buy Item",
      dialogue = {
        text = "What would you like to buy today?",
        choices = {
          {
            text = "Sword",
            action = buySword,
            dialogue = {
              text = "Here's your sword. Thank you for your purchase!",
            },
          },
          {
            text = "Shield",
            action = buyShield,
            dialogue = {
              text = "Here's your shield. Thank you for your purchase!",
            },
          },
        },
      },
    },
    {
      text = "Who are you?",
      dialogue = {
        text = "I'm the weapons keeper. You can buy swords or shields from me.",
      },
    },
  },
}
This would basically be an example format for an NPC dialogue table. It'd start at the top level, showing the text property. Then it reads if the dialogue has choices. If so, displays them all to the user and waits for them to select one. When they select the choice, the choice's "dialogue" property becomes the new displayed dialogue, and the process is repeated until the current dialogue doesn't have a "choices" field. The action field is an optional function that can be called whenever a choice is selected, such as, buying a weapon, or opening up a shop GUI for instance.

For example, here, the shopkeeper will ask "how may I help you", then display the choices "Buy Item" or "Who are you?". If you select "Buy Item", the text "What would you like to buy today?" will be displayed, then the choices "Sword" and "Shield". Whichever you pick, their subsequent dialogue text will be shown, and the dialogue will end.

Here's a raw Lua implementation to get somewhat of an idea of how you'd implement something like this.

Code: Select all

function buySword()
  print "You've bought a sword!"
end

function buyShield()
  print "You've bought a shield!"
end


shopkeeperDialogue = {
  text = "Hello! How may I help you?",
  choices = {
    {
      text = "Buy Item",
      dialogue = {
        text = "What would you like to buy today?",
        choices = {
          {
            text = "Sword",
            action = buySword,
            dialogue = {
              text = "Here's your sword. Thank you for your purchase!",
            },
          },
          {
            text = "Shield",
            action = buyShield,
            dialogue = {
              text = "Here's your shield. Thank you for your purchase!",
            },
          },
        },
      },
    },
    {
      text = "Who are you?",
      dialogue = {
        text = "I'm the weapons keeper. You can buy swords or shields from me."
      },
    },
  },
}


local dialogue = shopkeeperDialogue
while dialogue do
  print(dialogue.text)

  if dialogue.choices then
    for i,choice in ipairs(dialogue.choices) do
      print(i, choice.text)
    end

    io.write('> ')
    local choiceNum = io.read('*n')
    local choice = dialogue.choices[choiceNum]
    if choice then
      if choice.action then
        choice.action()
      end
      dialogue = choice.dialogue
    end
  else
    dialogue = nil
  end
end

User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Menu structure

Post by s-ol »

There is this HTML-JS interactive storytelling engine whose name I forgot; it's basically a dialogue system. It has an editor but no way to save or export the result other than HTMl AFAIK, so you would need to write a little JS export and a fitting Lua library.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
Muris
Party member
Posts: 131
Joined: Fri May 23, 2014 9:18 am

Re: Menu structure

Post by Muris »

S0lll0s wrote:There is this HTML-JS interactive storytelling engine whose name I forgot; it's basically a dialogue system. It has an editor but no way to save or export the result other than HTMl AFAIK, so you would need to write a little JS export and a fitting Lua library.
Maybe you mean Twine: http://twinery.org/

Making branching story telling doesn't sound exactly easy to do thing. You probably need to have a states for various choices, not to mention a possibility to skip some of the things you've planned. Maybe player doesn't do something you expect or skips some part of the game. The simpler you make, the easier it is to control the thing.

There was similar topic in the forum couple of months ago, but sadly I wasn't able to actually find the topic. Maybe finding that topic could give bit more info.
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Menu structure

Post by s-ol »

Muris wrote:
S0lll0s wrote:There is this HTML-JS interactive storytelling engine whose name I forgot; it's basically a dialogue system. It has an editor but no way to save or export the result other than HTMl AFAIK, so you would need to write a little JS export and a fitting Lua library.
Maybe you mean Twine: http://twinery.org/

Making branching story telling doesn't sound exactly easy to do thing. You probably need to have a states for various choices, not to mention a possibility to skip some of the things you've planned. Maybe player doesn't do something you expect or skips some part of the game. The simpler you make, the easier it is to control the thing.

There was similar topic in the forum couple of months ago, but sadly I wasn't able to actually find the topic. Maybe finding that topic could give bit more info.
Yes! I think that was it.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
Bindie
Party member
Posts: 151
Joined: Fri Jan 23, 2015 1:29 pm

Re: Menu structure

Post by Bindie »

Thanks for views on this. Basically I didn't want to go with the inefficient way I developed. I'm not going to post that solution since it was inefficient. (If someone really wants to I can of course make some example code).

Kingdaro, your way seems efficient at least from my view.

I'm curious, does io.read('*n') stop the game as io.read() does? I want to get in making my code more effective.
User avatar
Nixola
Inner party member
Posts: 1949
Joined: Tue Dec 06, 2011 7:11 pm
Location: Italy

Re: Menu structure

Post by Nixola »

Yes, it will. If you don't want to stop the game but you need terminal input, I'd look into [wiki]thread[/wiki]s. I reckon you can io.read from there (otherwise I'm not sure how Bartbes' Repler works)
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 42 guests