Community
SCI Programming => SCI Syntax Help => Topic started by: MusicallyInspired on May 05, 2010, 04:11:18 PM
-
I guess this should have been in the Syntax Help forum. My bad.
I know you've given up on the parser, Cloudee, but if you or anyone else has any insight into how this works I'm all ears. I'm trying to handle some said strings to do different things for "get silver key" and "get gold key". But I can't seem to figure out how to use qualifying adjectives. Sentences are split into three parts and so only two "/"'s are allowed. Any ideas? Can you use the semantic operator "<"?
EDIT: Apparently the semantic operator doesn't work either. Here's my code. Any idea how I can script in adjectives? Just putting a space between the words makes the compiler complain that there is no "gold key" or "silver key" word in the vocabulary list. But it's impossible to have 2-word words in the vocabulary list. So I'm stumped.
Here's the code I have that doesn't work:
(if(Said('get>'))
(if(Said('/gold<key'))
(if(not send gEgo:has(INV_GOLDKEY))
(if(== gCoffinOpen TRUE)
(if(== gCoffinOccupied FALSE)
(if(send gEgo:has(INV_PILLOW))
(if(<= send gEgo:distanceTo(Coffin) 5)
PrintOK()
(send gEgo:get(INV_GOLDKEY))
++gKeyQuest
(send gGame:changeScore(5))
)(else
PrintNotCloseEnough()
)
)(else
PrintDontSeeIt()
)
)(else
PrintDontSeeIt()
)
)(else
PrintDontSeeIt()
)
)(else
PrintAlreadyTookIt()
)
)
(if(Said('/silver<key'))
(if(not send gEgo:has(INV_SILVERKEY))
(if(== gCoffinOpen TRUE)
(if(== gCoffinOccupied FALSE)
(if(== gDraculaDead TRUE)
(if(<= send gEgo:distanceTo(Coffin) 5)
PrintOK()
(send gEgo:get(INV_SILVERKEY))
(send gGame:changeScore(2))
)(else
PrintNotCloseEnough()
)
)(else
PrintDontSeeIt()
)
)(else
PrintDontSeeIt()
)
)(else
PrintDontSeeIt()
)
)(else
PrintAlreadyTookIt()
)
)
)
-
I still can't figure this out so for the moment I'm going to just make him pick up both keys when you type "get key". If anybody ever has any ideas on figuring this out, please let me know.
-
Yeah, maybe I should rename the board to something besides how to, your not the first to post a question in there, no biggie. Anyway I'll fiddle around with it some this weekend, hopefully, and see if I can't come up with something. It's been a while since I've played kq2 are the keys in the same spot? like on a table together or something...
-
Yes. In Dracula's coffin there are (potentially) two keys. The gold key that opens the final door to the tower realm is underneath the pillow. The silver key appears after you kill Dracula with a stake and mallet while he's sleeping in his coffin, after which he disintegrates into a pile of ashes. If you kill Dracula and pick up the pillow there are two keys that you are able to pick up. I've programmed in every other state. I just need to figure out how I can program "get silver key" and "get gold key".
-
I havenlt tried it yet, but my first inclinations would be to make 3 said phrases. Turn gold and silver into nouns and if said gold, if said silver, and if said key. I think as long as the gold or silver comes before the just key phrase in an if else statement then it would return them? but I don't know it might not like two nouns in the users parse phrase. But that is the direction I would try.
-
I'll try it. But it still bugs me. Why is there a Qualifying Adjective flag in Vocabs.000 at all?
-
Yeah so I couldn't get it to work right. I managed to get it to respond correctly to "get key gold" and silver, but that really doesn't help. I'm out of ideas right now but I'll keep mulling it over. It's almost as if only the first and last word are recognised and everything else is ignored. I remember having similar trouble trying to do a top and bottom drawer. I think in the end I tossed out the idea and went with one drawer. ;P For now, I guess my best suggestion would be to give them whichever key is visible and if they both are then give them both...
-
It's still going to be frustrating for players who will instinctively type "get gold key" only to have it fail on them. I had the same problem with trying to type "get basket of goodies" at the mailbox. In the end I had to just do "get basket" and "get goodies". ANNOYING!
-
Hey, so I've been building a vocab.000 file from scratch and I think it is possible to have 'multiple part' words. I discovered this with mokalus's utility which I found on the agigames site for converting a words.tok file (agi) to a vocab.000 (sci). I ran it against an agi game and imported the resulting file into SCI Comp, and sure enough, I have words like 'bolt of lightning'.
I'm still in the process of building a vocab.000 file from scratch, and I'm thinking of perhaps making a utility which allows you to construct an entire vocab file from a spreadsheet. Alternately, you could always create a 'multi part' word in the vocab file with all the spaces replaced with an arbitrary printable character, then export the resource & edit it with a hex editor, replacing your bogus character references with a 0x20 (space character) and then re-import the file into your game.
The one thing that I'm not clear on is if the parser can handle these words. Part of me thinks that it probably chops a sentence up using the spaces, but maybe not necessarily?
-
This may seem like a silly response, given that I have not really looked at SCI scripting, but is it possible to declare a global variable that could be assigned a two word value?
-
Yes, you can declare a global variable that can contain any characters (I *think*). What did you have in mind?
-
Wow! If you manage to get this working it would be INVALUABLE to my KQ2 remake! I have to settle with things like "basket" and "goodies" instead of "basket of goodies" or "girl" instead of "red riding hood".
-
Okay, I've had more time to do some testing with this. It appears that despite the fact the vocab will support a multi-part word, the Said() string doesn't (it looks like it parses each word individually). I'm now hoping that perhaps I can substitute the spaces in the Said() string with an equivalent escape sequence.
I used some code like:
(if(Said('bolt of lightning'))
Print("You can't do that!!!")
)
and I couldn't get it to match it (it is interesting to note that each word *individually* needs to be in the vocab for the sentence to even parse, otherwise you get the response "I don't know the word 'xxx'"). All I get is the boiler-plate "You've left me responseless".
I'm really starting to dislike the parser...
-
I'm starting to think that the parser interface in the SCI template game is unfinished. Other Sierra games have no problem using adjectives. The function is even there in SCI Studio/Companion, but there is no explanation as to how to use it!
-
Okay, I haven't given up on this yet. Going back to your original post, I was able to get 'take gold key' and 'take silver key' to work properly. Here's what I did:
(if(Said('take/key<gold'))
Print("Ahh! The gold key!")
)
(if(Said('take/key<silver'))
Print("Ahh! The silver key!")
)
Typing simply 'take key' resulted in neither response being displayed. I ran this test against a brand-new template game, didn't have the touch to vocab at all. Does this help?
-
Thank you! I will test this!
-
Didn't work for me. Even though I had take/key<gold and take/key<silver after take/key it still decided to ignore both of them and gave me the take/key description.
-
Huh. Did you run this on a brand new template game? Maybe if 'gold' and 'silver' are not described as *only* qualifying adjectives in your vocab it might not work? Oh I should have mentioned that I put my 'take/key' logic after the 'take/key<gold' and 'take/key<silver'. I'll try it again when I get home (I was pretty tired late last night) - maybe if it still isn't working for you I could just upload the game to this thread and you could give it a go.
-
Oh I should have mentioned that I put my 'take/key' logic after the 'take/key<gold' and 'take/key<silver'.
Ah! That did it! :) Thanks for figuring this out. Why this stuff isn't properly documented I'll never know....this should go in the How To tutorial thread.
Unfortunately, I can't figure out how to use this for stuff like "basket of goodies". I can make it work with "take goodies basket" in-game but "take basket of goodies" isn't recognized....I thought the parser was smart enough to figure this stuff out.
-
Right, I was concerned about the 'basket of goodies' as well. That's why I tackled the keys first. I'll give it a shot, but I think part of the problem is that 'basket' and 'goodies' are both nouns. What about some permutation of this (total shot in the dark - untested)
(if(Said('take/basket<(of goodies)'))
Print ("ah, the goodies!")
)
Maybe the grouping using the parenthesis might help in this case? Or could you make the 'basket' and 'goodies' synonyms so they would collapse to a single noun?
-
Then you'd basically be saying "take basket basket" in-game which would return an error. And, in your example, words in brackets are just a collected series of "ORs". It doesn't acknowledge both of them at the same time. At any rate, I tried it and it fails.
I just wish Brian would have documented the parser a lot more than he did. He basically through a simple tutorial together and expected everyone else to understand it. In fact, he had that attitude for almost everything script related. Not everyone's a natural programmer...maybe that's why SCI Studio never really garnered much attention.
As a side note, it's nice to have active members tackling problems again. Feels like 3 years ago again :).
-
I've tried a few other things and I'm stumped. I actually started researching English parts of speech to better understand what we are up against. Here is what I found:
'Basket of goodies' - the word basket is actually a 'collective noun', whereas 'goodies' is the noun (plural of course), and 'of' is a 'containing preposition'. Lesson over.
My take on it is that the failure is in the parser building a correct parse tree or the Said() function properly interpreting it (covered my bases there). I'd bet that the whole mess just doesn't support the collective nouns. I think it's just not handled in the SCI spec, rather than it being a failure of Brian to properly implement the parser/Said() function within Companion/Studio.
My only idea is to scour other SCI games to see if they have anything with the same/similar sentence structure that is handled properly. Then at least we would know if this is even possible - maybe contact the author for some insight (if they can be found).
The good news is that you can actually type 'take basket of goodies' into the user input box & it *does* parse successfully. I guess there might be the outside possibility that we could override the Said() function and handle it ourselves (that might take a bit of doing).
-
Why is the word 'of' in the vocab then? It also seems silly that (once again) the SCI engine is incapable of something AGI did with ease.
Also, In King's Quest I SCI you can type "get four leaf clover" and it will work. There's no prepositions, but it's there. I'll look for other examples as well.
-
Hey, anybody have a copy of Space Quest 3 handy? I had an idea to test: Does the parser work with 'take orat on a stick' or 'eat orat on a stick' (or even more complex sentences, possibly involving an additional noun)? This seems pretty darn close to our test case.
-
you can't "take" it but you do "buy" it from Fester's store. And on a recent playthrough test for ScummVM I did indeed type "buy orat on a stick" and it worked.
-
It might also be useful to check out the times Sierra's parser gave them trouble too. Those few times when "the" had to be used to make the sentence work. Maybe your basket of goodies fits under the same situation. I'm not sure though since I can't think of one of those times.
-
Okay, I've starting coding to fix this problem. Here is my process and thoughts behind it:
1. Intercept the user input text event (I've found where this is in the User.sc script)
2. Go through the string input, looking for our problematic phrase (basket of goodies) - I hope the string kernel functions will play nice...
3. Replace our phrase with a simpler noun (replace 'basket of goodies' with 'basketofgoodies' or something like it - it will have to be in our vocab file)
4. Throw a new user input text event with our crafted string (I have an inkling of a clue here, please if anyone has done something similar to this before, chime in).
So instead of making the parser do what we want, I'm thinking of boiling down the inputted text to something the parser can deal with, so we can have a Said() string like this:
(if(Said('take/basketofgoodies'))
Print('Finally! You've taken the basket of goodies!')
)
-
3. Replace our phrase with a simpler noun (replace 'basket of goodies' with 'basketofgoodies' or something like it - it will have to be in our vocab file)
This is what I was thinking about when I asked if a variable could be declared from a string of more than one word.
-
Gotcha. So right, we will need a pair of variables for each phrase we want to intercept & handle specially: one string to represent the phrase that the user inputs and a second string to what it maps to.
-
Progress report: I've got everything working with the exception of the procedure that actually performs the find and replace. I've trapped the event, parsed the input, modified the input and re-fired the event. This will absolutely work, but I need the create the last piece; It looks as if must play with the string kernel functions - these are maddeningly under-documented. The only source of documentation is the SCI Studio html docs and anything I can gleam from forums.
I did some searching here & on the Mega-Tokyo forum looking for anyone who had already created a find-and-replace string function, but it was slim pickings. I'll ask the question anyway: Has anyone run into or developed on their own string function/procedure? Does anyone have any related string manipulation code to share?
-
After another 3-4 hours, current score is....
Character arrays/kernel string functions: 3
me: 0
I'm getting irritated...
-
Ah! 6 hours did it. Brain death complete.
Hey MI, looks like X-Mas came a bit early this year for the both of us! I think this problem is solved. Here is the complete solution for the 'basket of goodies' problem:
First, modify the User.sc (you should be able to find the (existing) outer if statement)
(if( (self:getInput(pEvent)) and Parse(@inputStr pEvent))
= teststr @inputStr
(if( == STRINGS_EQUAL StrCmp(teststr "take basket of goodies"))
findAndReplace(teststr "basket of goodies" "basketofgoodies")
= pEvent (Event:new())
Parse(@findAndReplaceStr pEvent)
)
(send pEvent:type(evSAID))
(self:said(pEvent))
)
Also add these new procedure in the User.sc
(procedure public (getChar inputStr index)
(var indexChar)
Format(indexChar "%c" StrAt(inputStr index) )
return(indexChar)
)
(procedure public (findAndReplace sourceStr findStr replaceStr)
(var i, findStrIndex, returnStrIndex)
StrCpy(@findAndReplaceStr "")
= findStrIndex 0
= returnStrIndex 0
(for (=i 0) (<i StrLen(sourceStr)) (++i)
(if (<> StrAt(sourceStr i) StrAt(findStr findStrIndex) )
StrCat(@findAndReplaceStr getChar(sourceStr i))
= findStrIndex 0
) (else
(while (== StrAt(sourceStr (+ i findStrIndex)) StrAt(findStr findStrIndex))
++findStrIndex
)
(if (== findStrIndex (+ StrLen(findStr) 1))
StrCat(@findAndReplaceStr replaceStr)
= i (+ i findStrIndex)
) (else
StrCat(@findAndReplaceStr getChar(sourceStr i))
++returnStrIndex
= findStrIndex 0
)
)
)
)
Then add a new global variable in the Main.sc script
findAndReplaceStr // This is for holding our modified parsed input
Oh, and don't forget to add 'basketofgoodies' into the vocab - otherwise the User.sc won't compile. Any time you've got a new 'compound noun' to add, just throw additional find-and-replace logic in the User.sc & also update the vocab.
Now you can do this in your room scripts:
(if(Said('take/basketofgoodies'))
Print("You got the goodies basket!")
)
Improvements can be made here, obviously we don't really want to have to specify every possible Said string - what I should do is fix that 2nd if statement that determines if the user types 'take basket of goodies' & change it to just detect if the words 'basket of goodies' are in it. Guess I'll do that next...
-
Nice! I'll give this a try later today if I have time! Sweet!
-
Uh-oh. After executing the findAndReplace function, if navigation of the ego is attempted, the game crashes after a few steps are taken (ego gets totally corrupted on-screen & game locks up). Hmmmm...
-
All fixed! I've also added a 'contains string' function so we can use 'basket of goodies' in ANY context.
User.sc - note that the 'getChar' function is removed - it was causing the crashing
(if( (self:getInput(pEvent)) and Parse(@inputStr pEvent))
= teststr @inputStr
(if (containsStr(teststr "basket of goodies"))
findAndReplace(teststr "basket of goodies" "basketofgoodies")
= pEvent (Event:new())
Parse(@findAndReplaceStr pEvent)
)
(send pEvent:type(evSAID))
(self:said(pEvent))
)
...
(procedure public (findAndReplace sourceStr findStr replaceStr)
(var i, findStrIndex char )
StrCpy(@findAndReplaceStr "")
= findStrIndex 0
(for (=i 0) (<i StrLen(sourceStr)) (++i)
(if (<> StrAt(sourceStr i) StrAt(findStr findStrIndex) )
Format(char "%c" StrAt(sourceStr i))
StrCat(@findAndReplaceStr char)
= findStrIndex 0
) (else
(while (== StrAt(sourceStr (+ i findStrIndex)) StrAt(findStr findStrIndex))
++findStrIndex
)
(if (== findStrIndex (+ StrLen(findStr) 1))
StrCat(@findAndReplaceStr replaceStr)
= i (+ i findStrIndex)
) (else
Format(char "%c" StrAt(sourceStr i))
StrCat(@findAndReplaceStr char)
= findStrIndex 0
)
)
)
)
(procedure public (containsStr sourceStr findStr)
(var i, findStrIndex )
= findStrIndex 0
(for (=i 0) (<i StrLen(sourceStr)) (++i)
(if (== StrAt(sourceStr i) StrAt(findStr findStrIndex) )
(while (== StrAt(sourceStr (+ i findStrIndex)) StrAt(findStr findStrIndex))
++findStrIndex
)
(if (== findStrIndex (+ StrLen(findStr) 1))
= i (+ i findStrIndex)
return TRUE
) (else
= findStrIndex 0
)
)
)
return FALSE
)
And now, in the room scripts we can do this:
(if(Said('take/basketofgoodies'))
Print("You got the goodies basket. It's pretty heavy...")
)
(if(Said('eat/basketofgoodies'))
Print("You eat the whole basket of goodies, and promptly toss your cookies!")
)
The last improvement that I see is to perhaps put the mapping of 'basket of goodies' to 'basketofgoodies' in a text resource, or a global array, or something so that we can define and iterate through all the 'complex nouns', rather than have to repeat the if-blocks over-and-over for each one.
Anyone got any ideas on that one? Here is the specific section of code that needs 'generalization':
(if (containsStr(teststr "basket of goodies"))
findAndReplace(teststr "basket of goodies" "basketofgoodies")
= pEvent (Event:new())
Parse(@findAndReplaceStr pEvent)
)
(if (containsStr(teststr "pieces of eight"))
findAndReplace(teststr "pieces of eight" "piecesofeight")
= pEvent (Event:new())
Parse(@findAndReplaceStr pEvent)
)
... etc, etc, etc...
-
What about recognizing different phrases the user might input, such as "goodies basket", basket of stuff, etc.? Would you repeat the same function for every possibility? If so, would that lead to heap errors? Perhaps it could be modified in a way that you could list all possible strings within the same function.
-
What about recognizing different phrases the user might input, such as "goodies basket", basket of stuff, etc.? Would you repeat the same function for every possibility? If so, would that lead to heap errors? Perhaps it could be modified in a way that you could list all possible strings within the same function.
Yeah, every single combination of words that we would want to 'collapse' (i.e. basket of goodies to basketofgoodies) would have to be set up, which would result in a pretty big (and possibly heap error-prone) User.sc script.
However, your statement made me think of just generalizing this even more. Maybe we could just look for the keyword 'of' and grab the words on either side of it & collapse it. Then it would be just one statement. I'm thinking something like this:
(if (containsStr(teststr " of ")) // Make sure you have the leading & trailing space so we truly are matching the 'of' word (avoid matching to 'roof' for example)
findAndReplace(teststr " of " "of") // Replace ' of ' with just 'of', which would effectively collapse our word
= pEvent (Event:new())
Parse(@findAndReplaceStr pEvent)
)
Hey, this might work great! However, now 'of' cannot be used in ANY other context. The use of the word 'of' in the user input would always result in a collapse. But that might be ok in this case. Thoughts?? Oh, and can anyone think of other words we want to do this to?
-
Remember, not all modifiers will use "of". A player could type "take goodies basket." What if you replaced the string with a variable that could be replaced by all possible strings? Does the SCI scripting include an "OrIf" that could allow a list of all of the possible strings that fit the variable.
Perhaps a better way would be to treat the modifier as another noun, i.e. either "take goodies" or "take basket" would also place the item in the inventory.
-
Remember, not all modifiers will use "of". A player could type "take goodies basket."
Yeah, hadn't considered phrases that don't utilize a modified (or if the user omitted it).
What if you replaced the string with a variable that could be replaced by all possible strings? Does the SCI scripting include an "OrIf" that could allow a list of all of the possible strings that fit the variable.
I don't think there is an OR operation that works against a set of data (or a string of delimited values). Also, I'd probably have to change the 'findAndReplace' function call, because the parameters would need to be correlated which we can't do with OR logic.
Now I'm leaning toward putting all possible combinations in a text resource & iterating over it to get the results we want. Dunno.
-
"Get Goodies Basket" is already possible at this point in the same way that "Get Silver Key" is possible. It's the addition of the word "of" that's the most problematic.
-
But, for example, would the phrase "put goodies basket on table" work ok? I guess if 'goodies' is classified as an adjective it would? Yeah, I guess it would. I'm just thinking about the '3 part maximum' that the parser splits the phrase into...
-
Quick update: The 'of' logic I previously posted with did not work. I'm not going to bother looking into it. I'm moving forward with implementing a text resource.
-
Man what an annoying fix this is. I wish Brian was here and cared enough to explain it...
-
Man what an annoying fix this is. I wish Brian was here and cared enough to explain it...
I think the problem I was running into most recently ('of') is due to whitespace comparison (but I was doing it before and it was/is working!). It's not a big deal and now the pain has been felt & I think I've got decent handle on string manipulation. Hopefully we will have a full solution buttoned up in the next few days...
-
Here is the final result. I've moved (almost) all the logic out of the User.sc & Main.sc to keep it cleaner. I did find out the problem I was having earlier was due to the null-termination of the strings which totally fouled up my matching process.
1) Create a new text resource file & put the full text of the nouns to be handled there
Examples: basket of goodies, pieces of eight, pile of bodies
2) Add new nouns to the vocab.000 file according to what you put in the text resource, without any whitespace
Examples: basketofgoodies, piecesofeight, pileofbodies
3) In the game.sh file, define a new constant COMPLEXNOUN_TEXT and assign it the number corresponding
to your text resource file above
4) Add the following code into the User.sc script
(use "ComplexNoun") // add this near the top, we'll create this script in step 5
// Then find this code block below & insert the line for the 'handleComplexNoun' procedure call
(if( (self:getInput(pEvent)) and Parse(@inputStr pEvent))
handleComplexNoun(@inputStr pEvent)
(send pEvent:type(evSAID))
(self:said(pEvent))
)
5) Create a new script file called ComplexNoun.sc and include the following code
(include "sci.sh")
(include "game.sh")
/******************************************************************************/
(script 972) // This may need to be changed if this number is already in use
/******************************************************************************/
(use "main")
(local
findAndReplaceStr
)
(procedure public (handleComplexNoun inputStr pEvent)
(var i,complexNounFull[50], complexNounStripped[50])
= i 0
(do
GetFarText( COMPLEXNOUN_TEXT i @complexNounFull)
(if (containsStr(inputStr @complexNounFull))
findAndReplace(@complexNounFull " " "")
StrCpy(@complexNounStripped @findAndReplaceStr)
findAndReplace(inputStr @complexNounFull @complexNounStripped)
Parse(@findAndReplaceStr pEvent)
)
++i
) while ( > StrLen(@complexNounFull) 0)
)
(procedure public (findAndReplace sourceStr findStr replaceStr)
(var i, findStrIndex char )
StrCpy(@findAndReplaceStr "")
= findStrIndex 0
(for (=i 0) (<i StrLen(sourceStr)) (++i)
(if (<> StrAt(sourceStr i) StrAt(findStr findStrIndex) )
Format(char "%c" StrAt(sourceStr i))
StrCat(@findAndReplaceStr char)
= findStrIndex 0
) (else
(while (== StrAt(sourceStr (+ i findStrIndex)) StrAt(findStr findStrIndex))
++findStrIndex
)
// >= comparison to handle match at end of string (null terminator)
(if (>= findStrIndex StrLen(findStr))
StrCat(@findAndReplaceStr replaceStr)
= i (+ i (- findStrIndex 1))
= findStrIndex 0
) (else
Format(char "%c" StrAt(sourceStr i))
StrCat(@findAndReplaceStr char)
= findStrIndex 0
)
)
)
)
(procedure public (containsStr sourceStr findStr)
(var i, findStrIndex )
= findStrIndex 0
(for (=i 0) (<i StrLen(sourceStr)) (++i)
(if (== StrAt(sourceStr i) StrAt(findStr findStrIndex) )
(while (== StrAt(sourceStr (+ i findStrIndex)) StrAt(findStr findStrIndex))
++findStrIndex
)
(if (== findStrIndex (+ StrLen(findStr) 1))
return TRUE
) (else
= findStrIndex 0
)
)
)
return FALSE
)
6) Don't forget to recompile the User.sc script. You can now use logic like this in your room scripts (or whereever):
(if(Said('move/pileofbodies'))
Print("Probably better to just leave those poor souls alone."
)
(if(Said('eat/basketofgoodies'))
Print("You eat the basket of goodies, and promptly toss your cookies!")
)
(if(Said('take/piecesofeight'))
Print("You pick up the pieces of eight")
)
-
If it workd, you should definately post that in the how to section
-
Yeah, it works, but consumes all of the heap (or pretty close). Found that out this morning. I don't see how it possible, going from 20K heap size to 0 with that code. I'm going to beat up on it more today...
EDIT: Got it fixed. Now utilizes minimal heap space (less than 1K). Who knows what the problem was. Will post complete write-up in the how-to section soon
-
... Got it fixed. Now utilizes minimal heap space (less than 1K). Who knows what the problem was. Will post complete write-up in the how-to section soon
Sweet, that's about what the guage script costs to run.
-
Nice! I need to find time to implement this...
-
Very nice tutorial indeed. I see you've got some of your check actor code in there. Now if we can get Brandon, or was it you, that figured out the gold/silver key syntax to stick it in there quick, the two topics will always show up together.
-
Very nice tutorial indeed. I see you've got some of your check actor code in there. Now if we can get Brandon, or was it you, that figured out the gold/silver key syntax to stick it in there quick, the two topics will always show up together.
Whoops! I didn't mean to have the actor stuff in there. I'm going to do another how-to for that. I'll throw in the stuff about the keys too...
-
I just love it. After I have a solution to this problem, I can't still can't let it go. It is solvable without any special code...
(if(Said('take/goodies<basket<of'))
Print("You got the goodies basket!")
)
Here is how the vocab needs to be defined:
basket - noun
goodies - noun
of - preposition & noun
There are a few tricky things I ran into. Leave both 'basket' and 'goodies' as nouns. You can (optionally) make the 'basket' an adjective, but don't make 'goodies' an adjective. Then you have to make 'of' a noun (you can leave it a preposition).
I figured this out through a brute-force technique. I was able to get 'take/goodies<basket' working first (just like the other example 'take/key<gold') then started inserting 'of' at all possible positions in the string. When I exhausted all possible combinations, started changing the word classes.
We desperately need some deep working knowledge of the parser dumped into a how-to. I mean all possible combination of said string examples possible. Nobody should ever have to figure this stuff out on their own. Not like this.
-
Dear God, YES. Absolutely ridiculous. If there's one thing about SCI0 game development that needed to be thoroughly documents from day one it's the parser. So cool that you figured it out, though (somewhat)! It's just too bad that "Take goodies basket" can't also work. You'd think that since "of" is a proposition that it would automatically accept "Take basket of goodies" as an alternative to "Take goodies basket". In the same way, it should also accept "Take basket with goodies" since with is also a preposition and it still makes sense. Maybe it's a bug in the implementation. I guess we won't really know until someone reverse engineers or decrypts a game script from an existing Sierra game.
-
Too bad that we couldn't ask one of the old Sierra developers for input. Scott Murphy can be contacted on Facebook, but he would probably be too keen about it.
-
I have half a mind to write a utility that allows you to enter an input string, specify what (ideally) you would like the word class of each word to be, and it would try every possible permutation of said strings, shuffling tokens around until it would be able to parse the input string. And the result would be the syntax of the said string.
This feels like all sorts of laziness to me. Not from a development standpoint, but an unwillingness on my part to fully understand the parser front-to-back. However, I'm not sure that I care. Do I want to be spending my time messing with trying to get the parser to take my input, or do I want to be working on more rewarding game-development endeavors?
Rant complete.
-
I have half a mind to write a utility that allows you to enter an input string, specify what (ideally) you would like the word class of each word to be, and it would try every possible permutation of said strings, shuffling tokens around until it would be able to parse the input string. And the result would be the syntax of the said string.
Oh yeah, it's on. I've already started coding this.
-
It's just too bad that "Take goodies basket" can't also work. You'd think that since "of" is a proposition that it would automatically accept "Take basket of goodies" as an alternative to "Take goodies basket". In the same way, it should also accept "Take basket with goodies" since with is also a preposition and it still makes sense.
The tool I'm developing is already paying off.
All your examples solved with 'normal' (if one can call it that...) parsing. First, set up the vocab:
with - preposition
of - preposition & noun
basket - noun
goodies - noun
// responds to 'take basket of goodies'
(if(Said('take/goodies<basket<of'))
Print("take/goodies<basket/of")
)
// responds to 'take goodies basket'
(if(Said('take/basket<goodies'))
Print("take/basket<goodies")
)
// responds to 'take basket with goodies'
(if(Said('take<with/basket/goodies'))
Print("take<with/basket/goodies")
)
And my favorite one that I was originally testing with:
// responds to 'take large sword from troll'
(if(Said('take<from/sword<large/troll'))
Print("take<from/sword<large/troll")
)
I don't think I ever would have figured that one out. I just don't find it intuitive. It had 24 permutations & worked on the first try. I can't wait until we have a library of examples documented.
The pattern I see emerging is that prepositions are 'semantically applied' to verbs & adjectives (and nouns) are 'semantically applied' to other nouns. We'll get this figured out yet.
-
Niiiice.
-
Now that I reflect upon it, the whole idea of a 'complex noun' falls apart (except perhaps from a Said() string simplification). It sure appears that a complex noun can be accomplished by linking multiple nouns together with the semantic reference The part we were missing was just making the individual words all nouns.
I'll update the how-to.
-
Okay, the app is completed. It accepts a user input string of 5 words or less (I wish it could be more, but 5 words creates 240 different said() strings - 6 words creates 1800 - heap space gone). It will output a rm001 script, which can be copied into a fresh template game, and run. When run, the user inputs the same input string they specified with the utility, and the correct said() string syntax is printed to the screen. Pretty cool.
But I'm still not satisfied. I just realized after completing this that it is simply the beginning of another application. After we figure out the parser, the next application will accept any length user input and will output the correct said() string (without the parsers' help) straight out of the command line app.
I've uploaded it to mediafire (it will live here soon...).
http://www.mediafire.com/?9xlq64vquvb8c5v
-
Whoa.
-
Another very old topic, but:
assuming basket is a noun, and goodies is a noun.:
'get/basket/goodies' will respond to "get basket of goodies"
and if goodies is also qualifying adjective, then
'get/basket<goodies' will respond to "get goodies basket"
Not sure how to have a single said spec match both of those...