Friday, July 13, 2012

another color oddity

So, today I was adding INPUTCOLOR support to my colorlib extension. After making my changes, I made a test case where the INPUTCOLOR changed every turn. Oddly enough, my game wasn't showing my input colors.

Eventually, I figured out that Hugo interprets:
color <first value>, <second value>
as:
color <first value>, <second value>, MATCH_FOREGROUND
This means that hugolib routines like PrintStatusLine, Menu, and CenterTitle automatically overwrite any non-default input colors you have set. I have updated the relevant routines in roodylib.h and newmenu.h, but anyone who is using non-default input colors in their game(s) should be aware of this.

Thursday, July 12, 2012

colorlib coordination

Yesterday, I was thinking how I probably should have coded the "colorlib" extension so that it saved and checked the input color (what the player types), too. I pretty much skipped it since, in my experience, it is not used a whole lot, but Robb Sherwin has used it a couple times in his games to nice effect.

It would have been nice had I coded it right the first time, but oh well. Anyhow, the main reason I'm posting here is to share a bit of advice that I learned in my colorlib-writing process. If you create a global variable meant to hold color values (example: TEXTCOLOR, MENU_TEXTCOLOR, etc.), it is best to define it with a default value, like:
global TEXTCOLOR = DEF_FOREGROUND
(TEXTCOLOR is defined this way. MENU_TEXTCOLOR is not.)

The importance of this is because later on, you might want to check if a global has a value, but this is easily confused by the fact that the color BLACK equals 0. Giving it a default value (default interpreter color constants range from 16 to 20) ensures that a 0 value always means BLACK.

Tuesday, July 10, 2012

more debugging stuff

I updated the "roodylib suite" file today (roody.gerynarsabode.org/notdead/roodylib_suite.zip). First off, it fixes a couple things in the included shell file that were caught by Royce Odle (yes, the Royce Odle of Hugo by Example fame). Secondly, I threw in some more debugging commands that are available when the HUGOFIX flag is set. The first two commands are SCOPE and SCOPE ROOMS, meant to remind an author exactly what the player can "see" at any point. SCOPE just checks what is available in the current room, while SCOPE ROOMS makes a list for every room in the game. I previously had shared the code for these routines on Hugo by Example, but in priming it for roodylib, I made a couple things work nicer. The other thing I did was add a VERBTEST <object> command. This is my attempt to emulate an extension that Juhana Leinonen made for Inform 7. It automatically barrages an object with a bunch of library verbs, as a way to remind yourself of what kind of obvious commands a player might use.

So yeah, hopefully, those are somewhat useful.

Lately, I've admitted to myself that I should probably start looking into filing my extensions in some source code management system, but I haven't yet looked into my options. Hopefully some of them are pretty simple. Also, rights-wise, I probably can't choose some open source site for any extensions that use standard library code (like roodylib).

Saturday, July 7, 2012

that menu thing

Ok, so yesterday, my prime coding time was spent at a coffee house where my laptop didn't have a lot of privacy. In such scenarios, being a full grown man (fuller than I'd like, even), I don't like people to see that I am obviously working on a game. As my current WIP has cover art and music and looks much too "game-like", I jumped right into working on that menu thing right away, as I basically knew everything I wanted to do and could spend most of my time in my text editor.

Doing the auto-generating thing was easy. The hard part (which I got to today) was writing the rest of the menu, which was the "About Hugo" and "How to Play Interactive Fiction" sections. Anyhow, I just finished working on it for today. Some of it needs to be completely rewritten; the current "About Hugo" page reads: Hugo is an interactive fiction authoring system written by Kent Tessman. It supports graphics and music!. The "What is interactive fiction?" page could use a lot of work, too, and honestly, everything probably needs some smoothing over.

Still, I'm pretty pleased with how it came out. You can take a look at it yourself by downloading the file at http://roody.gerynarsabode.org/notdead/colortest.hex. Inside the game, type "ABOUT".

The third option in the first menu is the auto-generated one. It has two groups of commands in there, based on the fact that colortext.hex was compiled with colorlib.h and cheaplib.h.

Anyhow, feel free to give me your thoughts or provide me with a nice, professional sounding "About Hugo" page or something. I should get all of the updated files uploaded in the next day or so. After that, it'll just be a matter of writing Hugo by Example pages that cover all of the new stuff.

Thursday, July 5, 2012

how suite it is

Of course, every time I look at one of my library extensions, I usually twiddle with this or that, so it's hard to promise that anything is done or complete (it'd help if my code was more foolproof). Just the same, I've got the "roodylib" library in a place that I'm happy with it. I wrote up some documentation and threw in some optional libraries in the form of "colorlib" and "cheaplib". I also included a roodylib-optimized shell file.

All in all, some aspects of "roodylib" are still too fiddly for my tastes, but oh well. I hope it's good enough that I can put it down for a while. Anyways, you can download the "roodylib suite" at http://roody.gerynarsabode.org/notdead/roodylib_suite.zip

Next library-related thing I'll do is that auto-generating help menu thing I talked about (which, unfortunately, will require an update to roodylib, I'm sure), but before that, I mean to actually work on game-writing for a little bit (game writing seems so much less fun sometimes).

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.

Monday, July 2, 2012

updates

Today, I wrote that color-support extension I mentioned the other day. I don't remember if I mentioned it already, but I also threw together the optional "cheap mode" extension on Friday. Unfortunately, I was too lazy to write code in these libraries to support non-"roodylib" usage. I tried to keep non-roodylib support in my updates to the various libraries, but now it's all kind of a jumbled mess so I'm not even sure. I figure I'll give roodylib and the updated libraries their own page on HbE to quarantine them for a while.

Anyhow, after a day away this weekend, coming back to work on these things wasn't the rewarding challenge I was hoping it'd be, so I think I'm starting to get a little burnt out. I'll try to use my waning attention in the next couple days to organize and document what I've got so people can take a better look at it.

Next on the agenda (when I feel like working on the agenda) is:
  1. NewMenu, like the Menu routines it borrows from, looks for a default menu if not given a particular one. It doesn't come with an example menu, so in a way, the extension feels kind of like it's "shipping" a defective product. I was thinking it should come with a default menu that comes with three options. The first option would be general information about Hugo itself. The second one would a thing on general IF commands. The third one, though, would be the interesting page, as it'd write itself based on what libraries have been included. For instance, if my new cheaplib or colorlib libraries are included, it'd automatically inform players of the "COLORS ON" and "CHEAPMODE OFF" commands. Authors would be free to alter or replace the default menu completely, but there'd be a functional menu there without any effort.
  2. Another thing to consider is a better way to automate file inclusion.
  3. See if I can update my "newconverse" update to play nice with "roodylib" 
An issue to ponder-
One of the things that "roodylib" does that I am overly fond of involves the status bar. In glk, once the status window has been drawn, it is not possible to make it disappear with a "window 0". Often, when you restart a game, the status bar will show the last session's information until the first time PrintStatusLine is called (which may be a keypress or two away, depending on the length of the introductory text). Instead of trying to fix that by clearing the status bar at the beginning of the game- showing a blank bar- I thought it'd be cooler to write something up there. I wrote some code where if the constant GAME_TITLE is defined, it prints that. Otherwise it just prints "HUGO INTERACTIVE FICTION". The end result looks pretty sharp. In fact, if someone turns cheap mode on in a cheaplib-enabled game it just shows that all of the time.

So, that's all fine and dandy, but in a regular, non-cheap-mode session, "window 0" does work, and it looks kind of cool to have no status bar up until the first PrintStatusLine of the game hits you. Unfortunately, though, this can cause some problems if there is a long opening, as the start of the intro text gets all of the way to the top of the screen, and when we get to PrintStatusLine, the new status window can cause text corruption or cover the top of our intro text completely.

So, the question is, should even regular interpreters get the "HUGO INTERACTIVE FICTION"/GAME_TITLE window treatment just to avoid buffer/screen issues? I have not yet committed myself to an answer yet.