FAQ Search Memberlist Usergroups
Jolt Country Forum Index
Register Profile Log in to check your private messages Log in
Log in Log in

Roody's Lessons Somewhat Learned

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Jolt Country Forum Index -> Hugo's House of Horrors
View previous topic :: View next topic  
Author Message
Roody_Yogurt



Joined: 29 Apr 2002
Posts: 1993
Location: Milwaukee

PostPosted: Wed Jul 28, 2010 4:40 pm    Post subject: Roody's Lessons Somewhat Learned Reply with quote

I'm one of those guys who tries to write IF despite having almost no programming knowledge. Death To My Enemies would not exist without some help I received coding an array.

Anyhow, I've been keeping track of the problems I'm running into and their solutions since picking Hugo back up earlier this year. I'm going to share them here. Hopefully, some of it will help other people for whom programming is new.

Here's just a bunch of stuff to start off with:

scoring

I've noticed a couple things wrong with the routine PrintScore(end_of_game) in hugolib.h. First off, the line "print ranking[(score*100)/MAX_SCORE*MAX_RANK/100]" should end with a ";". As it is, there is a new line where there shouldn't be, resulting in something like:

Quote:
You have scored a total of 10 out of 10, giving you the rank of MASTERMIND
.


Secondly, I've found that the default equation didn't work for my 30 point/ 4 ranked game. The comment describes it as thus:

! A complicated formula, since only
! integer division is allowed:
!

So I was led to believe that irrational numbers were screwing things up. In my game, I've replaced the line with "print ranking[(score*MAX_RANK)/MAX_SCORE];" MAX_RANK in this instance is the number of ranks, not including the ranking for 0 points. Anyhow, this may not be a perfect equation but it has worked in all of the examples I tested it with.

attributes vs. properties

In my Hugo game-coding so far, I found that I liked to check the state of my objects with the "special" attribute (examples: see if the player had searched something yet, whether something was broke or functional, etc.). The trouble with this is that I'd need another attribute if I had an object with more variables to check, and I was a bit confused about whether new attributes needed to be aliased to other attributes.

Eventually, I realized I could do a lot of what I was doing with properties instead. Properties don't only need to be used for drinks.left counts in soda can objects and the like. One of the results of this method, I've found, is that my new properties make the code easier to read since their names are usually a bit more specific than "special," and one property can be assigned as many states as I want instead of just the is/is not aspect of an attribute.

proper before/after usage

As mentioned in the manual, before and after have usage specifiers like object, xobject, actor, and location. In some instances, I found myself trying to catch verbs with the wrong usage specifier (using object or xobject when I should have been using location or actor). I think because object and xobject were the easiest for me to grasp, I gravitated towards those options unnecessarily.

Be sure to take a look at the order of before routine checks on page 127 of the manual to help determine where you need to catch a verb.

restart without prompt

In a joke game I wrote for a friend, I had a computer on which you could play the game you were already playing, so I wanted "play game" to act like "RESTART" without the "are you sure? y/n" prompt.

Now, this is kind of a horrible idea and shouldn't be emulated, but I thought I'd share the code in case a similar problem comes up for someone else for whom the answer isn't instantly obvious.

(In the game, the text adventure was on a phone, so >PLAY GAME would set phone as special and then Perform(&DoRestart) )

Code:
player_character you "you"
{
   before
   {
      actor DoRestart
         {
            if phone is special
            {   word[1] = "yes"
               if YesOrNo = true
                  {
                  if not restart
                  VMessage(&DoRestart, 2)  ! "Unable to restart."
                  }   
            }
            else
            return false
         }
   }
}


It's worth noting that this approach did not work:

Code:
   before
   {
      actor {
         if verbroutine = &DoRestart
      


edit: It occurs to me that all I need to do to force a restart was to add this code to the >PLAY GAME response:
Code:

       if not restart
       "huh, it didn't restart"

capitalized nouns

I recently found that Hugo hates them (well, at least, it refused to let me refer to my character within the game). I'm sure it's mentioned somewhere, but it's just one of those things someone like myself might forget (and did).

clearing the screen

My work-in-progress uses Christopher Tate's converse.h extension, which uses the status line for dialogue choices during conversations. I found that restarting the game while in conversation left the choices on the top of the screen no matter how many times I put in lines changing status line height or cls's in my init code.

Johnny Rivera suggested I put "window 0" early in my init. This did the trick. I would suggest anyone who finds themselves in a similar situation do the same.


Last edited by Roody_Yogurt on Thu Jun 23, 2011 6:33 pm; edited 1 time in total
Back to top
View user's profile Send private message AIM Address
Bainespal



Joined: 09 Jul 2010
Posts: 151

PostPosted: Thu Jul 29, 2010 9:08 am    Post subject: Reply with quote

The only programming I've ever done has been my many experiments with trying to write IF. Some of these sound like situations that I'll probably encounter eventually. In particular, the advice about properties versus attributes is well appreciated, as is the warning about the bug in the PrintScore routine. I'm planning on having some kind of scoring system, and your example has surely saved me some frustration. Also, I would never have thought to put the code for the modification of the Restart command in the PC object!

Thank you!
Back to top
View user's profile Send private message
Isxek



Joined: 15 Aug 2009
Posts: 10

PostPosted: Tue Aug 03, 2010 12:30 pm    Post subject: New version of Hugo? Reply with quote

Has anyone heard back from Kent regarding Hugo's progress? The last version was from way back 2006.

I know I've asked this before on the other forum (www.intfiction.org/forum), but hopefully - maybe - Kent has mentioned something recently about updating Hugo in the near future. (Maybe even creating a web-based 'terp :D )
Back to top
View user's profile Send private message Visit poster's website
Roody_Yogurt



Joined: 29 Apr 2002
Posts: 1993
Location: Milwaukee

PostPosted: Mon Jan 03, 2011 3:30 pm    Post subject: Reply with quote

First off, as an answer to that last question, Kent was just pining the other day for a time when he'll be able to make some tweaks to Hugo. He's currently dedicating himself to another project, but he definitely hopes to return to it.

Back to things I've been learning!! Woo!

So, last night, I was trying to code something where an impromptu... um... prompt pops up, asking you to name this thing, at which point I wanted to change the self.name on the object.

That ended horribly. After much trying, I found the Vault of Hugo sample code (and section of the Hugo manual) where it explains that for that kind of stuff, you need to do dictionary entry stuff. Anyhow, I will take another look at that another day.

Still, I've also been curious if I were to ever have a word puzzle in my game, how I would do it- again using a prompt and accepting any non-dictionary word and matching it to the correct answer.

Merk has code for stuff like that in TTS (routine DoSayString in newverbs.h, routine IsEqual in utils.h, and the tempbuf arrays), but I was in denial that Hugo didn't have something built-in that I could use to do the same thing.

I did eventually get something to work. Now, Hugo stores the last quoted string in parse$. I found that to compare parse$ to another string, you first have to transfer it over to an array, at which point you use StringDictCompare, not StringCompare. If the two strings are identical, StringDictCompare returns as zero so your code should check for such.

Here is an example:

Code:

!somewhere up top
array names[10]

! down in the game code
"The puzzlebot turns to you and asks, \"What is in the middle of holes?\""
GetInput("type SAY \"ANSWER\"")
string(names, parse$, 10)
if StringDictCompare(names, "l") = 0
      print "Correct!"
else
           print "Wrong!"


Interestingly, the case of the letter provided by the player doesn't matter. I doubt this example is the most durable of code, but there you have it, some quick and easy puzzle answer shouting.
Back to top
View user's profile Send private message AIM Address
Roody_Yogurt



Joined: 29 Apr 2002
Posts: 1993
Location: Milwaukee

PostPosted: Tue Jan 25, 2011 11:06 am    Post subject: Reply with quote

I did eventually get the naming thing working right. I just modified the Vault of Hugo example to work with what I already had so far.

Anyhow, let's go on to other things I have learned. In the category of 'basics I forget and have to relearn every so often':

- Verb routines have to return true for the turn counter to go up and PrintStatusLine to be updated.

- Before and after routines that do not specify verbroutines are applied to all verbs, like

Code:

before {
           object
                   {
                    "Never mind the object!"
                    }
           }

(of course, you'll probably also have to trap for 'xobject' and so forth.)

- I still occasionally forget that you can't use parentheses over multiple lines and must use braces

- A quick alternative to 'if word[3] = "donkey" or word[3] = "mother"' is 'if word[3] = "donkey","mother"'

- In the last game I finished, I had forgotten the correct way to end a game. I was trying to call the routine EndGame(#) (with # being the endflag), when really (and somewhat unintuitively), all you have to do is set the global "endflag = #"

Next time, I will go into some PreParse and ParseError stuff I have learned!
Back to top
View user's profile Send private message AIM Address
Roody_Yogurt



Joined: 29 Apr 2002
Posts: 1993
Location: Milwaukee

PostPosted: Tue Jan 25, 2011 11:28 am    Post subject: Reply with quote

So in my last joke game, I wanted to code some Easter Egg responses to some unimportant commands. I noticed the existence of PreParse and thought, hey, I can just check for some words and return true and never have to bother that Parser at all! The command in question was >THE HELL? so it especially didn't seem right to make some verb grammar entry for it.

The problem was that at least part of the parser is handled engine-side, so through normal methods, you can't just skip it. It turns out the only way to get the parser to shut up is to use ParseError().

ParseError lets you either replace parser error messages with something more fitting for your game. If you call ParseError(100) or higher, it calls the respective CustomError(). If there isn't a matching CustomError, it prints nothing, which is what we want in this instance.

So let's put the following code in player.before:
Code:

      actor PreParse
         {
         if (word[1] = "hell", "hell?")
            {
            "I know, right?"
         ParseError(100)
            }
         else
         return false
         }

("hell is word[1] because "the" is ignored)

Initially, I had hoped that doing things this way would leave no parser clues that certain commands are understood, but since this seems to add "hell" to the dictionary, the parser will always admit that it recognizes it.

So the result isn't that much different from the verb grammar/verb routine route, but this way might save a little bit of time. and may be occasionally useful.
Back to top
View user's profile Send private message AIM Address
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Jolt Country Forum Index -> Hugo's House of Horrors All times are GMT - 7 Hours
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001 phpBB Group

Theme by Kage Musha - RPG Garden

Copyrights and trademarks are all of the belonging company. No copyright Infringement intended