[SOLVED] Verb-Noun Parser

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.
User avatar
Echo
Prole
Posts: 46
Joined: Fri Jul 13, 2012 4:50 pm
Location: Lucid Moon

[SOLVED] Verb-Noun Parser

Post by Echo »

I want to make a verb-noun parser for my visual novel game engine. A verb-noun parser is used to recognize input made as strings by the player. For example you could type in "open door", then the computer will use the verb-noun parser to recognize the word open as a verb, you are telling the computer that you want to open something but what? then it looks for a noun to attach this verb to, door is a noun, it is an object, then using the computers programmed logic it will link the two, open + door, it then recognizes this as a valid action and performs the task.
I know how this works in my mind but I have no idea how to code this from scratch in Lua, I have a hint that it involves something to do with converting variables into strings and vice versa, could be wrong though.

Any ideas for an algorithm or some sample code that could help me flesh this out? How would you even input text in Love during gameplay? Is it possible to have a sort of built in console or something just for this. Hope it wont get too complicated to do, I'm thinking of keeping it very simple, like you can only use commands with one verb and one noun,

Verbs would be:

Use
Open
Examine (Look)
Search
Move + Front, Back, Left, Right, (noun)
Take
Drop
Talk
Ask

Nouns would be general items and stuff like keys, doors, chairs, stairs, walls e,t,c ( the list is almost endless ) but will be in the following categories:

Pick-up ( stuff you can take and carry in your inventory like keys and small items )
Portals ( like doors and stairs, you interact with them to go somewhere )
Action ( these cant be picked up, nor do they take you somewhere but perform actions like sitting on a chair or interacting with someone )
Idle ( these don't do anything and are there in rare cases as obstacles such as walls and barriers )

Then I'm thinking we make a table for e.g pickups with

Code: Select all

pickup = {}
and add all the pick ups in that as variables then somehow we program a function to compare e.g key.pickup with e.g door.portal or something if we
need the key to open the door...

Hope this is all do-able, it doesn't have to be easy just possible.

I just really miss those old school adventure type games for their verb-noun parser, some retro VN's use the same mechanic in their game-play...
Last edited by Echo on Thu Nov 14, 2013 9:57 am, edited 1 time in total.
User avatar
juno
Citizen
Posts: 85
Joined: Thu May 10, 2012 4:32 pm
Location: London

Re: Verb-Noun Parser

Post by juno »

Sounds interesting!
I would say concentrate on getting the input working first. You would have to essentially program a textbox from scratch which would be done using the love.keypressed() function. Each time a key is pressed you append it to a string and print the string on the screen. You would also need to incorporate backspaces and such which could get messy.
wat ya mean she's in another castle!?
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Verb-Noun Parser

Post by Roland_Yonaba »

Oh, this is very doable.
First, to handle input, you will need a console.
Theres is no built-in console inside Löve, but you can easily code one for your purpose. Take a closer look at SomeguynamedPie's work or vrld's console, it should serve for your purpose or pure learning.

Second, for verb+noun parsing, you will simply have to collect the user input, parse it to find what's the verb, and what's the noun and act regards to that.
A naive approach should be as simple as follows:

Build a distionnary list of valid nouns, and of valid verbs using tables with string indexes.

Code: Select all

nouns = { sword = true, book = true, ...}
verbs = { walk = true, move = true, stand = true, open = true, ...}
Then analyse the user input string to parse the verb and the noun.

Code: Select all

local userInput = "open book" --example input
local verb,noun = string.match("(%w+)%s(%w+)") --parse the verb and the noun
if verb then assert(verbs[verb],("%s is i not a valid verb"):format(verb)) end --Checks if the verb is valid
if noun then assert(nouns[noun],("%s is i not a valid noun"):format(noun)) end --Checks if the noun is valid

-- Perform the corresponding logic using verb and noun variables
This is, as I said, a very minimalistic example and a very naive approach. Obviously, for a larger project, you will have to care about more things.
This should be a very interesting lecture.
User avatar
Echo
Prole
Posts: 46
Joined: Fri Jul 13, 2012 4:50 pm
Location: Lucid Moon

Re: Verb-Noun Parser

Post by Echo »

Thanks for the help but the consoles don't work how I intend, I wanted something like this
Image
You can still see the picture but enter a command in a console that is only at the bottom of the screen.

The console's you recommended either took up the entire screen when running or simple run and shut down like a native lua console.
I think I might have to write one from scratch in love.keypressed and code it in a message box since I don't think it is necessary to have
an entire lua console, I just need a way for the player to input text that could then be parsed and checked for validation then perform an action
which could be done undercover in the engine without a messy lua console obstructing the entire screen.

Thanks for the article, I'll read it and maybe look at some of the code used to create the native lua console in love just to see how I can create
input for the user and I'll just have to figure out how to use that input and have it parsed. This might not be as easy though...
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Verb-Noun Parser

Post by Roland_Yonaba »

Echo wrote: The console's you recommended either took up the entire screen when running or simple run and shut down like a native lua console.
I think I might have to write one from scratch in love.keypressed and code it in a message box since I don't think it is necessary to have
an entire lua console, I just need a way for the player to input text that could then be parsed and checked for validation then perform an action
which could be done undercover in the engine without a messy lua console obstructing the entire screen.

Thanks for the article, I'll read it and maybe look at some of the code used to create the native lua console in love just to see how I can create
input for the user and I'll just have to figure out how to use that input and have it parsed. This might not be as easy though...
Well, it seems you misunderstood my point.
Basically, all consoles works the same. As Juno said, you just have to create a string buffer, and feed it with characters each time the user presses a key, and terminate concatenation when Enter key or (another one) is pressed.
The links i've provided were not for direct use, but for learning purpose. Skimming through the code, you are likely to see how the console was implemented. So that if you have to write your own console for your game, you can use them as a codebase if you don't know where to start.
User avatar
Echo
Prole
Posts: 46
Joined: Fri Jul 13, 2012 4:50 pm
Location: Lucid Moon

Re: Verb-Noun Parser

Post by Echo »

yikes! (0_o)
I'm not touching that with a 10-foot pole...
User avatar
Echo
Prole
Posts: 46
Joined: Fri Jul 13, 2012 4:50 pm
Location: Lucid Moon

Re: Verb-Noun Parser

Post by Echo »

O.K, I might touch this after all...

I've been looking at some guys key pressed function to understand how to get the input working. I added numbering to make it easier to read...

Code: Select all

1     function love.keypressed(k,u)
2     if(k=="`") then Console:Toggle() return end
3      if(not Console:IsOpen()) then okp(k,u) return end
4      if(k=="backspace") then Console.text=string.sub(Console.text,1,#Console.text-1) return end
5      if(u==13 and #Console.text>0) then
6         s,e,r2,r3,r4=pcall(function() loadstring(Console.text)() end)
7         if(s) then
8            if(e) then
9               Console:WriteLine(e,math.random(255),255,math.random(255))
10            end
11        else
12            Console:WriteLine(e,255,0,0)
13         end
14         Console.text=""
15         return
16      end
17      if(u~=0) then
18         Console.text=Console.text..string.char(u)
19      end
20   end
21   return Console
22   end
23   function print(txt)
24   Console:WriteLine(tostring(txt))
25   end
I am going to bug you guys a hell lot until I understand EVERYTHING in this code since all of this seems extremely bleak and hostile to me so I apologize in advance for taking up so much of your time and being a newbie, but I've decided to get this done either-way since their are no visual novel engines with text parser technology and using something like Adventure Game Studio (however tempting) would be like trying to pick your teeth with a razor blade.

O.K lets get started:

Line 1: function love.keypressed(k,u)
I am assuming k is used as a variable that holds the current key being pressed. I don't know what u is.

I have no idea what line 2 and 3 are, I looked into the rest of the code but it' looks like gibberish to me.

Line 4: if(k=="backspace") then Console.text=string.sub(Console.text,1,#Console.text-1) return end
I'm guessing this handles removing text with backspace where text is a variable that holds the string input by the user

Line 14: Console.text=""
I think this makes the text disappear or cleared or something. the rest from line 4 to 14 probably controls the printing of text into the console
which might be important but I can't make any sense out of it.

wait, actually I think this controls the text input by the user ( line 23, 24 ,25 )

Code: Select all

function print(txt)
Console:WriteLine(tostring(txt))
end
There only 25 lines of code so this cant be too hard to interpret. I think

I dont get what kind of variable or function or whatever this is ( on line 12)
Console:WriteLine(e,255,0,0)
I think love handles the input with this one line of code...right?

Where can I find a tutorial on this stuff, how to create text input in love2d? I don't see it on the wiki.
I don't want to have to pick my teeth with a razor blade however much the toothpicks keep breaking and I have something really jammed in their! it's easy but I will lose all the blood I put into this!
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Verb-Noun Parser

Post by Roland_Yonaba »

You really need to pay attention to the wiki.
First of all, you can't get everything from this code, just because some parts are harcoded for specific purposes, and thus are beyond the scope of getting a simple input.
These articles on Lua's native string library should interest you, though.
Lua's string library (from PiL)
Lua's string library tutorial
Echo wrote: Line 1: function love.keypressed(k,u)
I am assuming k is used as a variable that holds the current key being pressed. I don't know what u is.
Key for the key pressed, u for the corresponding character's Ascii code.
love.keypressed
keyConstants
Echo wrote: I have no idea what line 2 and 3 are, I looked into the rest of the code but it' looks like gibberish to me.
And actually, you don't have to care.
Echo wrote: Line 4: if(k=="backspace") then Console.text=string.sub(Console.text,1,#Console.text-1) return end
I'm guessing this handles removing text with backspace where text is a variable that holds the string input by the user
You're guessing right.It removes the last characters from string Console.text
Echo wrote: Line 14: Console.text=""
I think this makes the text disappear or cleared or something. the rest from line 4 to 14 probably controls the printing of text into the console
which might be important but I can't make any sense out of it.
Sort of. Funy things happens here, but once again, that's beyond your needs, and you don't have to care.
Echo wrote: wait, actually I think this controls the text input by the user ( line 23, 24 ,25 )

Code: Select all

function print(txt)
Console:WriteLine(tostring(txt))
end

Not the input control, it just prints the input.
There only 25 lines of code so this cant be too hard to interpret. I think
Echo wrote: Where can I find a tutorial on this stuff, how to create text input in love2d? I don't see it on the wiki.
I don't want to have to pick my teeth with a razor blade however much the toothpicks keep breaking and I have something really jammed in their! it's easy but I will lose all the blood I put into this!
Well, handling text input could be as simple as the following.

Code: Select all

function love.load()
   -- some var
   input = ""
   -- some var
end

function love.draw()
   -- some code
   love.graphics.draw(input, someX,someY)
   -- some code
end

function love.keypressed(key,unicode)
   if key == "backspace" then
      input = string.sub(input,1,input:len() -1)
   elseif string.match(key,'%d') or (unicode >= 65 and unicode <=90) or (unicode >= 97 and unicode <= 122) or key == " " then
      input = input .. key
   elseif key=="return" then 
       -- perform logic (parse input, etc)
       input = ''
   end
end
User avatar
Echo
Prole
Posts: 46
Joined: Fri Jul 13, 2012 4:50 pm
Location: Lucid Moon

Re: Verb-Noun Parser

Post by Echo »

thanks yonaba, I was freaking out a little (0_o)...

O.K I'll calm down and look at that string library tutorial (p_p)
User avatar
Echo
Prole
Posts: 46
Joined: Fri Jul 13, 2012 4:50 pm
Location: Lucid Moon

Re: Verb-Noun Parser

Post by Echo »

I have a better idea, I've made a user interface...
Image
This solves the problem of input.

What do you think? I made it very simple for now, no color yet but I sort of like it like this...

Coding a good text parser is very difficult for me, even after reading about string libraries and patterns in lua (thanks for the links Yonaba).
but I do get an idea how to match patterns in lua, without the problem of getting the input to work, I think with an interface I can focus on the
actual meat of the matter which is matching verbs and nouns and creating an output.

This UI would work like this. lets say you want to open a door and move though it. instead of guess typing you simply select open, then click on the door
in the visual ( the huge black box would have a picture, you click on the door in that picture ) then the message box will display a message saying the door is now open. after you select move from the commands and click the opened door to enter.

What about smaller items that might not be easily visible? lets say you wan to search a cupboard and take what you find inside. You select the Search command, select the cupboard in the visuals, lets say you find a key, an envelope and a pen and you specifically want to take the key.
Under the Inventory menu there is an empty table with blank choice boxes, these will be used to display the objects in the cupboard.
Their arrows in-case there a lot of objects that exceed the 10 choice boxes ( like for a bookshelf with 25 books ). You can then select the key from the choice-box and then select an empty area in your inventory to keep the key in. If you want to use the key, you select the use command, then select the key in the inventory and then select what you want to use it on, like a door in the visuals or something.

This is all a lot more to code, but it's better for a more user friendly interface with an underground-inbuilt verb-noun parser doing all the magic...

Plus mouse input is easier to control than text input, you don't need to make a console or whatever...I thought it would be retro though but screw it GUI is better...this still looks retro right?
Last edited by Echo on Thu Aug 02, 2012 8:09 pm, edited 1 time in total.
Post Reply

Who is online

Users browsing this forum: Google [Bot], slime and 182 guests