Tuesday, July 3, 2012

init simplification / compression

The init routine in the "new shell" listed on Hugo by Example currently is as follows (actually, I took some comments out of it to make it even more readable here):
!:: Game Initialization routine
routine init
{

#ifset BETA
        if word[1] = "script"
                transcript_is_on = true
#endif
        word[1] = ""    ! clear word[1] in case of game restart
        MAX_SCORE = 0   ! ready to change for a scored game
        STATUSTYPE = 0  ! 0 = none :: 1 = score/turns :: 2 = time
        counter = -1    ! 1 step before first turn

        TEXTCOLOR = DEF_FOREGROUND
        BGCOLOR = DEF_BACKGROUND
        SL_TEXTCOLOR = DEF_SL_FOREGROUND
        SL_BGCOLOR = DEF_SL_BACKGROUND
        color TEXTCOLOR, BGCOLOR

        verbosity = 2

        display.title_caption = "<game title>"
! display.title_caption - used for GUI clients for title bar text.
        prompt = ">"
        window 0 ! resets the windows in case the player is restarting a game  
        cls      ! clear the screen, too

#ifset GLK
        glkcheck
#endif

        DEFAULT_FONT = PROP_ON
        Font(DEFAULT_FONT)

!:: Opening Text
        "Intro to game"
        print ""    ! For a blank line between the intro and the game title

        Font(BOLD_ON)
        "Game Title"
        Font(BOLD_OFF)
        "Game Blurb"
        print BANNER;

#if defined IFID  ! print the IFID, if there is one
        print IFID
#endif

        player = you
        location = STARTLOCATION
 
        move player to location
        old_location = location
        FindLight(location)
        DescribePlace(location)
        location is visited
        CalculateHolding(player)

#ifset USE_PLURAL_OBJECTS
        InitPluralObjects
#endif
}
 I've mentioned on here that I would also like to make init simpler, so authors new to Hugo can get to writing their games quicker (and are less likely to do something out of order, like trying to start a daemon before the location and player globals have been set). In one of my more recent test games, I got init down to this:
routine init
{
!: First Things First
SetGlobalsAndFillArrays
!: Screen clear section
SimpleIntro
InitScreen
!: Set up any special libraries
Init_Calls
!: Game opening
IntroText
MovePlayer(location)
}
 Of course, all of the same routines and lines of code are being run; they're just moved around into their respective routines. This is how I break it down:
  1. SetGlobalsAndFillArrays - This routine would reside nearby in the shell, as it requires game-specific information to be set.

    Example:
    routine SetGlobalsAndFillArrays
    {
    !\ Uncomment and modify this section if your game has scoring and ranking.
        MAX_SCORE = 50
        ranking[0] = "Amateur Adventurer"
        ranking[1] = "Competent Door-Unlocker"
        ranking[2] = "Bomb-Meddling Adventurer"
        ranking[3] = "Master Magic Wand Finder"
        ranking[4] = "The Genuine Article Sample Game Solver"
        MAX_RANK = 4  \!

        counter = -1                    ! 1 turn before turn 0

        STATUSTYPE = 1   ! 1 = score/turns, 2 = time, 3 = moves: score:
        TEXTCOLOR = DEF_FOREGROUND
        BGCOLOR = DEF_BACKGROUND
        SL_TEXTCOLOR = DEF_SL_FOREGROUND
        SL_BGCOLOR = DEF_SL_BACKGROUND
        prompt = ">"
        DEFAULT_FONT = PROP_ON
        player = you
        location = STARTLOCATION
    }
     
  2. SimpleIntro - A roodylib routine that prints some blank lines before a simple, non-glk game starts (sort of faking a clearscreen). This could be replaced if you wanted to do a cool logo like mentioned in another post.
  3. InitScreen - This is a screen clearing routine. The roodylib version has different behavior for simple, regular, and glk interpreters. It also sets the font and colors.
  4. Init_Calls - This automatically calls all library routines that need to be executed in init. I gave each library an object that goes into an init_instructions object. Init_Calls just checks for children of init_instructions and runs all applicable code.
  5. If any of the library routines print anything (like beta.h asking if the player would like to start a transcript), it returns a value telling Init_Calls to run InitScreen again so the screen is cleared before the "game proper" begins.
  6. Then, Intro_Text would be another "shell-side" routine. This is where the opening text of the game would go.
  7. MovePlayer automatically prints the location name and description.
All in all, I'm pretty happy with this system. I'm not sure if I'll recommend it for the "official shell", but I think I might distribute a "roodylib shell" with roodylib. The one other thing I'd possibly do is just add a dummy routine after Init_Calls so authors can just fill it with whatever other calls they want (even though they could conceivably add such routines to the end of SetGlobalsAndFillArrays).

Anyhow, I'm sort of conflicted about how I should handle this. On one hand, of course, I'm designing init so the author really has to change it as little as possible, but since that goes against init's traditional handling, I hope the new way isn't even more confusing. Ah well, time will tell, I guess.

No comments:

Post a Comment