Tuesday, March 11, 2025

Less-cited Hugo File Limits

 When it comes to limits in Hugo, authors are most familiar with the static limits that can be viewed or modifiable ones that can be set at compilation time.  If a game needs more arrays or routines than the system default, great, we change a value and we're good to go.

There are other limits in Hugo to be aware of, though, as discovered by Robb Sherwin.  More than a year ago, he noticed that some rooms defined late in the code in his WIP were not accessible.  I had a chance to use the Hugo Debugger on it and could see how, for no discernible reason, the code execution would just go off the rails once it reached the applicable object.  Changing the order of file inclusion made this object accessible while presumably breaking something else.

We figured at the time that some limit (besides the ones already mentioned) was being overwritten, resulting in a pocket of a corrupted code.  We couldn't deduce which limit we were running into, though.   It was time to consult either Kent Tessman himself or someone else well-versed with the Hugo file format.   We try to not bother Kent too much, though, as creating Hugo shouldn't be a CURSE OF ENDLESS QUESTIONS.  He has more important, family-providing things to attend to (buy Fade In Professional Screenwriting Software today!).   Similarly, we didn't want to bother others who have already done so much for Hugo, so the issue just kind of sat for a while.

Recently, it came up again and we tried to look at the problem with fresh eyes.  I pointed Robb to  Juhana Leinonen's Hugo .hex file inspector page, which verified that objects were redirecting to other things.

He also brought the issue up to Kent around this time, and Kent suggested that either the dictionary or properties table was the culprit.  Robb took out some words and things, and voila, everything works now.

So, the problem was solved, but I still wanted to find out what tools Hugo authors have to check for this.    The issues comes down to the design of the Hugo .hex file, which allocates 64K to the dictionary, special words, array space, events, properties, and objects each.  Hugo was designed to make games playable on 16-bit devices and these limits reflect that.  In Robb's case, he was surpassing that 64K dictionary limit.

One of the quirky things about Hugo is that it has a lot of great features that the documentation doesn't fully explain- either their usage or the situations in which something is especially useful.  Despite the fact that the compiler didn't complain about a too-big dictionary table, I figured that there must be something in there since, in my opinion, Kent really did a great job in planning for a lot of scenarios.

So before I wrote this post, I thought I'd look over the compiler switch options again (since there are several that most Hugo authors rarely use), and indeed, there is a -u switch that shows the memory usage of a compiled game.

Here is an example of a memory usage readout:

          (Top:  $013F44)

+-----------------+---------------+

| Text bank       | $001054 bytes |

+-----------------+---------------+

| Dictionary      |   $0B60 bytes |

+-----------------+---------------+

| Special words   |   $0080 bytes |

+-----------------+---------------+

| Array space     |   $0CE0 bytes |

+-----------------+---------------+

| Event table     |   $0010 bytes |

+-----------------+---------------+

| Property table  |   $0680 bytes |

+-----------------+---------------+

| Object table    |   $0700 bytes |

+-----------------+---------------+

| Executable code | $00FB60 bytes |

+-----------------+---------------+

| Grammar table   |   $0D00 bytes |

+-----------------+---------------+

| Header          |   $0040 bytes |

+-----------------+---------------+

        (Bottom:  $000000)  

So, the values are in hex so authors have the extra step of converting them to decimal, but hey, it can give us a general idea if we're approaching any of those table size limits.

At some point, I will probably take a look at the compiler source and see if it's within my simple capabilities to check for these limits.   In the meantime, I'll probably add a page to Hugo By Example drawing attention to this.   Of course, this whole issue only happens in a game with a lot of stuff so it's possible that Robb will be the only one to ever run into it!

Wednesday, July 10, 2024

Roodylib 4.3.0

 Announcing Roodylib 4.3.0-  some updates listed in the previous post and more in the changelog.


At the time of this post, the IF Archive upload is probably still in "incoming," but you can also download it right here.  The Hugo Notepad++ bundle (Notepad++ setup with a toolbar for quick compilation and execution of Hugo games) and Hugo Notepad++ add-on (files to add to an existing Notepad++ installation- doesn't include the toolbar, though).  I even made a Hugo Notepad++ 32 bit bundle, just in case that would be useful to anyone out there.

the last few months

 When I last updated Roodylib a few months ago, I found a bug shortly after, but I didn't think it was important enough to bother IF Archive maintainers with another upload so soon.  Anyhow, good news!  The last few months have been very successful in finding and fixing several bugs.

To avoid having to actually get back to writing games, I had decided to distract myself by getting back to the project of applying Roodylib to other people's games.  In the past, this has been a great way for finding shortcomings in functionality and ease of configuration.

Anyhow, the game I was returning to has several randomized events and a lot of character scripting and other things that just made the original task of adding Roodylib quite daunting.

It wasn't long before I ran into an instance where a character with a long character script was never reaching his destination.  At first it drove me a little crazy trying to figure out why the last few steps in the script were not happening.

Long story short (and yes, I can easily make it a long story), I found a bug in Hugo's library code.  Character scripts are supposed to have a maximum of 32 steps; instead, if there were multiple character scripts running, the second script was overwriting the first at the 17th step.

Anyhow, I fixed the bug and I was pretty excited about this.  When I first starting making Roodylib, I had never researched how versioning numbers are supposed to work so I just jacked the numbers up willy-willy whenever an update felt big to me.  Eventually, someone pointed out to me that the major, minor, and patch numbers actually stand for things.  In the years since, of course, Roodylib version numbers crawl up by much smaller increments since most updates fall under the "patch" umbrella.

So, to me, fixing a system from the original library was BIG and merited a minor number increase, and what can I say, I find that exciting.  Also, of course, I was happy to be able to have a good reason to put out a new release because of that bug I mentioned at the start of this post, too.

Luckily, the bug fixing did not end there, nor was the hunt even limited to the Hugo library/Roodylib.

While troubleshooting that game I had been adding Roodylib, too, I found a bug where, if I referred to a known object not in scope, if there was another known object not in scope that shared an adjective (despite different nouns), the first one defined would always be the one sent to ParseError;  of course, this is noticeable if the objects have different pronouns ("You don't see him here." when you are expecting "her").

After testing, it became clear that the problem was not on the library side.  I wrote one of the people behind one of the Hugo interpreters and asked him to look at the problem;  he said that he didn't have time right away but pointed out that the problem was probably in "heparse.c" (in the source).  When I read that, I thought, huh, it never even occurred to me that I might have the chops to be able to understand the engine code but, hey, it couldn't hurt to look.

I wouldn't say that it was easy, but Kent's code is commented and organized nicely and it was fairly clear where I needed to look.   Plus, I have to give props to all of the people who have contributed to making the Hugo unix port so easy to build on modern systems so I could tinker and test my solutions relatively quickly.

I found the bug and went around making pull requests at several github projects that use the Hugo source.  Gargoyle accepted it right away, and it was kind of a bucket list moment for me.  I've always wanted to contribute to an open source project but didn't think I had the programming chops for the opportunity to ever come up.  In the acceptance, it was explained to me that Gargoyle (and several of the other interpreters) inherit their code from the Hugo unix port repository, and somewhere along the way I was made a collaborator of that so I'll never technically have to do a pull request again, but it sure was satisfying to make one and have it accepted!

After that, I was digging through old joltcountry.com posts to see if there were any problems that new light could be shed on, and I found one about Hugo's inability to write (and correctly read) negative numbers when it writes to file.  Someone helped me come up with a solution.  It won't work in 16 bit interpreters (I don't even know the likelihood that anyone will ever build a 16 bit interpreter again), but that's fine; writing negative numbers would probably never be needed by a game author- it was more for interpreters that use Nikos' opcode system for special instances.

Some years ago, I noticed that if an xverb grammar definition (xverbs in Hugo are system verbs like "save" or "restore" that don't use up a turn) was more than one line long, the additional lines would be interpreted as a verb.  I decided to look into this as well.  I initially thought the problem might be in the compiler on this one, but it turned out to be another engine error.  I got that one, too.

So, three engine fixes!  Now, I imagine that we are probably years away from our next Gargoyle or Hugor or whatever release, but it's nice knowing that those fixes will be out in the public one day.

Anyhow, I've been kind of rambling on and on.  I'll just say that in these last weeks, I also fixed some problems with Hugo's plural/identical class system and I was pretty stoked about that (another good excuse for the minor increase in the upcoming version).  The rest, I'll just save for the new release's changelog.


Sunday, July 7, 2024

Hugo's >GET ALL behavior

 I've been doing a lot of Hugo poking and prodding in the months since my last post, and I'll soon be releasing an update to Roodylib and talk about all of the improvements.  One thing that came up in this time is particularly useful to authors, though, so I wanted to give it its own post.

In the last post, I mentioned how I gave a Roodylib-ized version of Kent Tessman's Spur to someone.  Since he quickly uncovered a daemon bug due to changes in the official Hugo library over the years (I talk about this a bit in the previous post), he switched over the original version at some point.

He noticed that the >GET ALL responses were different in the two games.  Now, Roodylib intentionally skips some items from >GET ALL as I personally feel a long list of objects you can't grab makes a game feel shoddier-coded.  On the other hand, I have some sympathy for the way that >GET ALL can sometimes be used as a sledgehammer to list as many of the objects in the room that can be interacted with as possible.

This got me thinking that maybe Roodylib should have an optional "kleptomaniac" mode where the >GET ALL rules are looser, something akin to verbosity settings.

While researching this idea, though, I found that Roodylib's behavior wasn't as different from the old behavior as I thought;  hidden objects were ignored in both (which is for the best as authors might use hidden objects just for scope purposes).  Roodylib normally skips over trying to get other characters, but turning that behavior off didn't result in the multiple lines of "You can't pick that up." that I had envisioned.

Roodylib also had some code borrowed from Future Boy! that disallowed >GET ALL from being applied to the belongings of other characters, unless the player mentioned them specifically (>GET ALL FROM BOB), but even after I took away that code, belongings of the character I was testing with were being ignored.

In my "kleptomania" test game, >GET ALL only added the ability to try to pick up characters, and that seemed more like a case of being grabby than the kleptomania that I was shooting for.

I eventually figured out the following rules:

  • If a parent object (character or not) has a false exclude_from_all property, >GET ALL only attempts to get the parent, skipping all of the children.  This is why when I turned on the ability to try to get characters, the other code became irrelevant.
  • If a parent object (character or not) has a true exclude_from_all property (which is Roodylib's default), all of its unhidden children are available to >GET ALL (which the Future Boy! code stops if it's being used).
I just think this is good for authors to know.   Say your game has a coffee table with some stuff on it the player may want to pick up.  Better to make the coffee table's exclude_from_all property true so a >GET ALL automatically tries to get all of its children instead of making players type >GET ALL FROM COFFEE TABLE.  If you don't want the children of an object to show up in >GET ALL, giving the parent a false exclude_from_all property is a quick way to stop that.

Additionally, the ExcludeFromAll routine is what you'll want to edit if you want more control over how the children of objects are handled.  This is where that aforementioned Future Boy! code is.

In the end, "kleptomania mode" was a bust since I don't think I can provide a "kleptomania mode" experience satisfyingly different enough from normal behavior without breaking everything.   Still, I learned something.

Thursday, April 25, 2024

2024 update

 Well, it's been three years since the last one, so I guess I'm due for a new Not Dead Hugo post.  In the past few months, I have been cracking open some Hugo code once again.

First off, a special shout out to the hundreds of bots who visit this blog every month.  Thank you, Hong Kong!  

I still have never learned any general purpose coding languages to the extent that I know Hugo.  I mentioned on here at one point how I wrote a Hugo "game" to coordinate my family's Secret Santa program.  It allows me to easily disallow Secret Santa matches from previous years so people don't get the same pick, and using game transcripts, it writes all of the picks to text files so I can be as surprised as everyone else, as far as who has picked whom.

In the last year, I decided that it would be nice to have a companion compilation that would allow my family members to look up Secret Santa's on their own (for the times you have a really inspired gift idea for someone so you would like to pass the idea on to their actual Secret Santa... or whatever other reason you might want to know).

So, I wrote this companion app.  The two programs shared a file that both could write to or read from (like I did in my joke game "The Halloween Horror").  For some reason, though, at first, values were getting overwritten by the second one.  I decided this merited some more in-depth examination of my "configuration file helper" extension, but by the time I got around to doing the deep dive, I had already redesigned my pair of "games" and was no longer able to replicate the issue.  Sometimes it's kind of disappointing when everything works, no longer able to figure out why anything ever went wrong.

Hugella over at the Jolt Country interactive fiction started a project to review all of the IF Archive's uploaded Hugo games at the tail end of 2022.  One of the early games covered was Robb Sherwin's port of the BBS door game "HAMMURABI."  Opening up the game myself reminded me that I once thought it'd be a good coding exercise to add some perks.  The main thing I wanted to do was to have the game use the normal Hugo engine game loop instead of 'while' loop so that meta commands like SAVE, RESTORE, and (most importantly) QUIT worked.  I also wanted to stop it from accepting negative numbers and other things that could easily mess up the game.

I thought about this idea in 2023 but I think I actually even gave up on it at some point, since Hugo only understands a few numbers as dictionary words by default and commands need to be understood for the game loop to work.

But there I was, in 2024, with new ambition and grit!  And I was successful (the new version is now up at the IF Archive, I believe)!  So that was fun.

There was a snag at one point, though.  My Roodylib code that turns inputted-numbers into actual numbers expected unrecognized words in the word array to have the value 0, and in my code, they were coming up as -1.  Part of me remembered seeing parse$ (the variable where Hugo saves unrecognized words) having the value -1 in the past, but I just figured I must have gotten something wrong.

So this (and another sort of meaningless update- just added some additional information at the start of game transcripts in games compiled in debug mode) caused me to upload a new version of the Roodylib suite and updated the Notepad++ packages.

Only after all of this was done did I discover the true culprit.  parse$ in a word array filled by the parsing engine gets the value -1, but parse$ in a word array filled by the input command has the value 0.  So future releases of Roodylib will allow for both values (since no legitimate dictionary word will ever have those values) but I'm not going to upload a new Roodylib suite right away.

In other Hugo news, I recently made the acquaintance of a blind IF fan so I was excited to share some Hugo games I've compiled with some accessibility stuff that strives to make games work better with screenreaders.  I don't think he noticed any of those features (which isn't a big deal since they are barely noticeable, to be honest), but he did notice that a daemon wasn't triggering properly in the game Spur.  While I was quick to suspect that some of my Roodylib updates had broken something, it turned out that some of Spur's 1999 daemon code doesn't play nice with the modern Hugo library.

It was easy enough to replicate the intended behavior in other ways, though, and I made a note about this Spur code over at Hugo By Example.  I've been trying to update Hugo By Example more in general.  Among a handful of pages, I added a step-by-step walkthrough on using the Windows Debugger as I get the impression that many Hugo authors don't take advantage of it.

In other project news, as someone who feels he has awful time management, I coded a thing in Hugo that randomly picks tasks I want to do and rewards I could have (again, I don't know any general coding languages well).  I used Hugo's system time stuff to determine what day of the week it is and what time of day so that some tasks can be limited to day or night or weekday or weekend, if need be.  Finding online equations for finding the day of the week was fun; I can't remember the last time I've needed the mod function for a game.  Still, it's unlikely that any game most people write will care if players are playing the game on a Monday so I don't think I'll be adding that code to any of the Roodylib libraries.

The plan is that I will work on my own game ideas at some point, but since working on my own games is the worst, I'll probably find one or two distraction projects to do before that happens. 

Thursday, February 18, 2021

More Necromancy

In awesome news, Juhana Leinonen was able to convert my old Hugo By Example backups and give it a new presence on github.  Hugo By Example was a wiki created by Royce Odle for learning Hugo, but sadly, it has been unavailable for several years now.  The things I learned while writing for it were largely responsible for the creation of Roodylib.  Even as one of its more prolific contributors, back in the days where I actually wrote games (gasp!), there were certain pages I referred to all of the time.  It's just great to have a resource where things like error message numbers and constant values (things that are not always covered to the full extent in the Hugo Book) are cleanly listed without having to dig through the Hugo library every time.

Hugo By Example was last updated in 2013 so in the coming weeks, I'll be focusing my attention at correcting statements that are no longer true, fixing dead links, and updating it with all of the changes we have seen since then.  I hope the site becomes as useful to someone else as the original was to me.

Beyond that, we also have a new hub (also created by Juhana) for all things Hugo collecting links to the current interpreters, repositories, and other resources that a Hugo user might need.

Personally, I'm very excited about these things.

Saturday, August 29, 2020

>FOLLOW SO-AND-SO "Which way did he go?"

 To be honest, returning to game design hasn't been going all that well, so recently, I thought I could distract myself by looking over an old Roodylib "to do" list to see if there was anything I still wanted to add.

The first thing that sounded appealing was trying to come up with a solution to Hugo's default handling of >FOLLOW, as a game seems kind of dumb when you have just seen a character leave a room and >FOLLOW responds with "Which way did he go?"

I wrote a system that relies on using CharMove to move your NPCs.  The code takes note of the direction the NPC left in, and unless the NPC returns at some point, >FOLLOW will result in going in the same direction.  There was no ultra-clean method that didn't involve replacing some routines, but this was the most elegant solution that I could come up with.  Beyond including this code, authors would just need to remember to give their roaming NPCs the "last_dir" property that I have defined.



After writing this, I wanted to test it out in a game.  I first tried "Guilty Bastards" because I incorrectly remembered being able to follow someone at some point (although it definitely has a character following you).  I then tried "Spur," which I was reminded was actually the game that inspired this whole better-following thing in the first place, but I couldn't even use my code with it as it completely substitutes another character script routine for CharMove.  I mean, sure, I could have rewritten it all so my code would still have worked, but in my sandbox version of "Spur", I had already written a >FOLLOW SO-AND-SO workaround anyway.

So I just had to test it with my own code, and hey, everything seems to be working fine.  I'll probably just throw it in the "extensions" folder in my Roodylib distribution at some point.





Saturday, April 11, 2020

4.2.1


So, I was testing the latest Roodylib with Juhana Leinonen's HugoJS interpreter, and it turned out that I had forgotten to incorporate some code from last fall which prevented Roodylib from causing games to hang.  Anyhow, it's in there now.

I also added an "opcode alternative" folder to the extensions so people can use Nikos Chantziaras' opcode-calling routine if they find Roodylib's less-direct method too confusing.

Yes, I skipped from 4.1.9 to 4.2.1 because even though I thought an April 4.2.0 release would be funny, I forgot about that whole Hitler thing and thought best to avoid it altogether, ha.

Roodylib 4.2.1 is here.  I've also updated the Hugo Notepad++ bundle and the Hugo Notepad++ add-on (for preexisting Notepad++ installations).

Sunday, April 5, 2020

Back From the Dead

So, first off, my apologies to anyone who was looking forward to more posts here during the last several years.  I was overwhelmed with some of the big changes I wanted to make to Roodylib to begin with, and then first my grandmother and then my father had health issues that took up all of my attention.  Sadly, they both passed away last year, but I'm thankful for all of the time I was able to spend with them.

I've had more time to get back to Roodylib in recent months, and I'm happy to be able to share the results.  I've uploaded a new version of Roodylib here.  I've also updated the Hugo Notepad++ bundle and the Hugo Notepad++ add-on (for preexisting Notepad++ installations).

As issue-tracking and version-numbering aren't really my forte, I have bumped this new release up to Roodylib 4.1.9, as it's basically an alpha I'd like to get out into the open (and my juvenile sense of humor thought it would be stupidly funny to put out a final 4.2.0 release later this month).  I've run it through a bunch of games with pretty much no issues except for changing how files are included, but one never can tell with these things.

Changes in this new release:

  • Right after the last official release, I noticed that Roodylib didn't handle multiple AGAIN/Gs in multi-command input.  Originally, I thought it was something I broke, but it seems that Hugo's library never handled it quite like I would want.  Anyhow, that's working now.
  • I moved whatever I could back to extensions for overall better code-readability for both Roodylib and the extensions themselves.  As much as I have loved the simplicity of just adding a flag to include functionality in my games, I decided that I have to keep future authors in mind so it's easier for them to see how each system works.  One side effect of this is that certain routines had to be broken up even further, so this new version of Roodylib grows in routine declaration despite being pared down in size.
  • Similarly, I redesigned some of the Hugofix stuff so extensions can easily add more debugging options without having to replace the entirety of some Hugofix routines.
  • I added some pronoun-choosing helper routines so games seem smarter.
  • Opcode functionality should be up to date and working on all existing opcode interpreters.
  • Improved some attachables stuff.
I didn't go all-out crazy making the documentation as perfect as possible, but a lot of this is covered in more detail in the Roodylib documentation.

There has been some other exciting Hugo news in recent months:
  • Juhana Leinonen released Borogove, which allows people to write Hugo games online (among several other types of game)!
  • Tristano Ajmone put The Hugo Book online.  With Kent's permission, updates and fixes have been made, making it the most accurate version of the book available.
  • Steps have been made to centralize the Hugo code base, and discussion of Hugo's future is underway.
So yes, exciting times.

Anyhow, to warn you, I don't really see myself updating Roodylib or this blog in the future with the same frequency as I did in years past.  While nothing is ever perfect, this version is basically the culmination of years-spanning intentions, and now that I've reached this point, it's likely that I'll move on to something else- whether that is back to game-writing or something else entirely, we shall see.


Sunday, March 26, 2017

progress report

In recent months, I've seen Hugo mentioned in some unexpected places, and Dannii Willis is working on a glk interface Hugo web interpreter (to which I say, the more the merrier!).  The downside of this is that it has made me more frustrated with the ways Roodylib might be unaccommodating to beginners.  I've decided against my previous "throw it all in" philosophy for Roodylib and have been moving whatever code I can to extensions, and taking out code I'm not 100% satisfied with altogether.  I just want the heart of Roodylib as simple and readable as possible.

Unfortunately, this calls for even more updating to the documentation, so that'll be yet another process.  As much as I'd like to get a new Roodylib out the door, the interpreter opcode side of things isn't as hammered out as I'd like it to be, either, so it'll probably be some time yet.

Just to make this post fun, I thought I'd share some Hugo games hard-compiled with the HugoJS behavior that should work by default once the opcode stuff is all working right.

The first game is "The Hugo Clock" by Jason McWright.  Written for a Hugo minicomp we held a handful of years ago, it's a good example of a game that, despite lacking deep narrative machinations, hits that sweet spot of just being fun to poke and prod around with: The Hugo Clock

The second game, "ScepterQuest", was originally written with Hugo 1.2, back in Hugo's DOS-only days.  I ported it myself as a coding exercise some years ago (and because I find the game very silly and funny), but I intentionally never uploaded it to the IF Archive.  Still, check it out, and if you like it, go ahead and break out DOSbox and try out the original: SceptreQuest

In other IF news:

  • Bob Bates' Thaumistry: In Charm's Way hit its kickstarter goal.  People can still donate through PayPal to hit the stretch goals.
  • Jesse McGrew released version 0.8 of his ZILF compiler.  I'm well overdue to post to my other blog, ZIL Crazy After All These Years, but I'm really happy with how ZILF is coming along.
  • Andrew Plotkin and Chris Spiegel have been looking for official platform builders for the Gargoyle interpreter, and any steps toward more timely updates of one of the most popular offline IF interpreters are greatly appreciated!
  • The 2017 Spring Thing competition is just about to start.  I'm so glad that Aaron Reed has kept it running all these years.
  • One of my favorite videogame publishers, Devolver Digital, released a compilation of text adventures from a game company called No Code.  It's called Stories Untold.  Unfortunately, even with my settings set way low, it runs too slowly on my computer (I'm not so nostalgic for early 80s text adventures that I want to bring back waiting minutes between commands) but I look forward to trying it again if I ever get a nicer computer.
Apologies to all of the cool IF news things I am missing!

Wednesday, January 25, 2017

down the rabbit hole of parsing

I've been wanting to write an update post just to assure those that care that I have been working on Roodylib stuff, but it's been hard to pull the trigger as I imagine parsing quirks isn't very interesting to most people.  Then again, if I knew of some blog that was one author's exploration of parser theory or battles against an existing parser, I'd probably read it.  Just the same, anyone who doesn't care can skip down to the "In other news" section below.

So, what with the release of HugoJS, I really want the next version of Roodylib to be as flawless as possible, both for the possible re-release of older games (so they operate best in all kinds of interpreters and make use of Roodylib's accessibility options) and for future games.  To this end, I've been making "recordings" (*) of games with available source and testing the playback against both the original and Roodylib-compiled version and then checking for errors.

( * In several IF systems, typing "RECORD" in a game will begin a transcript that only writes commands to a file.  Then, the next time you play the game, typing "PLAYBACK" will allow you to select the file.  At this point, the game plays all of the commands from the recorded file,  This is a great way to see how the same set of commands affects different versions of the same game.)

Luckily, several of the games have available walkthroughs to make this easier, but it's still slow going; many of the games have random elements so I "normalize" the random number generator to make them predictable.  Several of the games use a conversation system that handles choice entry through GetInput which isn't caught by recording/playback so I wrote a modification to the conversation system to allow making choices from the regular prompt.

I had finished going through a couple games (and, in the process, found a couple Roodylib bugs) when I caught a conversation where Jesse McGew speculated about optimal ZIL behavior when it comes to disambiguation questions within multiple-command inputs.

Say you have a command like this:
>EXAMINE BOX. GET IT. DROP IT.
The issue was, if the game responds with "Which box did you mean, the cardboard box or the glass box?" and the player chooses one, should it then proceed to process the rest of the command?  Inform does proceed, but making the player re-type the rest could be seen as a viable approach, as it is an error of sorts and every IF language is allowed its own expectations of how to handle such situations.

This got me curious about how Hugo/Roodylib currently handled it.  I found that if the player used the disambiguation system added by Roodylib (using "1", "former","2", "latter" and such to refer to listed options), it cleanly stopped processing the rest of the command, but if the player used the engine-based disambiguation system (typing in "glass" or "cardboard"), the rest of the word array got mangled and resulted in a "I didn't understand that." response.

First, I added some hacky code so the engine-based disambiguation also exited cleanly, but then I decided that I preferred the "KEEP ON PROCESSIN'" behavior and modified both versions to do that.

Unfortunately, this opened up another can of worms as I then noticed that the "G"/"AGAIN" code was somewhat broken.   Fixing this took quite a while as I had to re-acquaint myself with all of the parsing code.

Now, everything works again and, in fact, works better than it did before I started.  The old code, borrowed from the original Hugo library, only restored the last command when "AGAIN" is used, so a multiple command input like >SHAKE CAN. G.. OPEN IT.  would lose track of the rest of the command before it got to "OPEN IT". As in, when AGAIN is called, the entirety of the word array was replaced with just "SHAKE CAN".  Now successive commands are not lost and are properly parsed.

Now that I have it working, I plan to clean up the code a bit and maybe put in some hooks so authors can easily put in optional behavior.  For instance, if an NPC is given a command that is an xverb ("save","undo","restore"), Roodylib intentionally gives the error "That doesn't make any sense."  The previous Hugo behavior was just parsing it like all is well, likely leading to a "So-and-so ignores you." response.  So, I'm sort of considering putting in some kind of hook so authors can re-direct it to some kind of "So-and-so says, 'Do what now?'" response if they'd like.

As soon as I'm done with that, it's back to testing games, followed by more general code clean-up and documentation updates.  Given that real life has been fairly hectic and will be for the foreseeable future, this will be a multiple month process.

In Other News

Hugor's Nikos Chantziaras is credited on the development team for a new TADS 3 game by Bob Bates (of Infocom and Legend Entertainment fame).  "Thaumistry: In Charm's Way" is currently being funded on Kickstarter.  I was lucky enough to be in its first wave of alpha testers and found it to be quite a fun romp.  I've been watching the kickstarter progress obsessively and am really looking forward to the finished product.  I'm sure almost all readers of this blog have seen an announcement for it somewhere else, but I just wanted to throw my personal recommendation out there!

Wednesday, December 14, 2016

The 2016 Hugo Holiday Newsletter

December offers an exciting challenge to finish or improve the projects one has worked on through the year, and it's a great time to look back on progress already made. It's actually been a pretty exciting year for Hugo! Let's recap!

  • Nikos Chantziaras has continued making improvements to the multi-platform Hugor.  The opcode system he introduced in recent unofficial builds should make for a smoother player experience in the long run.  Some of the logistics of the opcode system are still being worked out (see below), but we probably can expect to see a new official build released in the coming months.
  • Robb Sherwin's work in progress, Cyberganked, has been greenlit on Steam.  Cyberganked is an IF/RPG hybrid like nothing the world has seen before, taking inspiration from games such as Wasteland and Bard's Tale.  The secret word on the street is that Sherwin's next game may be a sequel to one of his earlier works, so anyone who would like to see any of these things come to fruition should get involved with the Cyberganked community and help make this thing happen!
  • Jizaboz continues to work on his multimedia-enhanced North Korea simulator, A Day In DRPK.  From what I've seen of the work in progress, I believe it's more than two-thirds complete and most likely will be released in 2017.  You can check out the game's original demo here and check its progress here.
  • Juhana Leinonen accomplished the Herculean task of writing a Hugo interpreter in JavaScript.  HugoJS has a page where you can play any of a pre-selected list or use the link tab to play any .hex file from a URL.  The interpreter itself is quite snazzy.  Juhana had previously provided an Emscripten DOSbox solution which used the Hugo DOS interpreter.  HugoJS blows the old method away in speed, presentation, and ease-of-use on mobile devices.  My limited experimentation also led me to believe it should work decently with screen readers.

    Juhana has been updating HugoJS with Nikos' Hugor opcodes, and we've been in the process of adding new ones.  When all is said and done, Roodylib should work nicely with all existing and future opcode-enhanced interpreters.  It may even have multimedia support at some point, too.
  • Kent Tessman, author of Hugo, is busy updating and promoting his screen writing software, Fade In.  In recent years, it has been embraced by some of Hollywood's best screenwriters (and many others more) for its ease of use and astounding list of features despite being much cheaper than old "industry standard" solutions.
As for me, I'm working on updating Roodylib to incorporate the new opcodes and fixing some bugs.  I hope to have another official release within the next month or two, at which point I'll re-release all of my games so people can see all of the new functionality.


Wednesday, September 7, 2016

roody labs

My latest bit of Hugo coding has been comprised of distracted yet productive meandering.

*  * *

Roodylib takes several important Hugo library routines and breaks them up into several routines for the sake of readability and modification (I'd rather provide authors with a method to change just the important thing instead of having to switch out the entire 126 lines of FindObject).  Of course, one side effect of this is that it greatly increases the starting number of routines in any given game.  The Hugo default max limit of routines is 320.  Now, this is a changeable, soft limit, but it worries me when a Roodylib game creeps up to that 320 limit; I don't want it to get to the point where my beginning advice to new authors includes how to raise the routine limit.  They have enough things to take in at that point.

DescribePlace, the routine responsible for room descriptions, was one that I split into several routines so authors had the ability to change the order in which things are listed.  To combat the creeping-routine problem, I redesigned the routines as objects with one routine to execute them.  It's actually been done for a while, but I didn't mention it because it's kind of a useless modification, all things considered, and the number of routines probably only bothers me.

* * *

I also modified the "shell" files included with Roodylib to automatically compile with the -s switch.  This provides compilation statistics like number of objects, routines, etc.  I always find this useful; I figure others will, too.

* * *

Sir Jiz has a lot of timers in his game- most of which he's been handling with the room each_turn property.  I usually do this by keeping the number-of-turns-spent-in-room in the misc property so the each_turn property routine can have some "select self.misc" code and go from there.  Long story short, Jiz was getting sick of reminding himself where the best place to set the misc value was.  I figured, ah, yeah, I guess Roodylib could do something about that.  So now there's a RoomTurnCount thing so nobody has to mess with misc anymore.

select RoomTurnCount
case 0
"Runs as soon as player enters room."
case 1
"Runs after first turn."
case 2
"And so on."

Although maybe I should have pushed him towards using a daemon instead.  Ah, well, always nice to have multiple ways to do things.

* * *

Some months ago, someone expressed interest in there being a Hugo Comp this year, so I tried to gauge interest from everybody at the joltcountry.com forums and throw some theme ideas around.  I had been in the middle of playthrough of "Spellcasting 201: The Sorcerer's Appliance" so I figured a magic-themed comp would be fun.  I even offered to throw together an extension for authors to use so they wouldn't have to write the magic system themselves.

I started off by looking at Cardinal Teulbachs' (yes, back in the olden days, we used to have an IF community member named "Cardinal Teulbachs") take on a spellcasting system.  His code strictly prohibited modification, though, so I was going to have to write my own thing by scratch (I don't always honor code licenses, but hey, this time I did).

I think I came up with the base design for my system, but I decided I needed to refresh my memory on how spells worked in the Enchanter trilogy (how many memory slots the player has, if all spells can be memorized multiple times- stuff like that).

The funny thing, though, is that I found myself super distracted by the fact that you could not read dropped scrolls in Teulbachs' sample game which was a departure from expected Infocom behavior.  Just the same, it made some sense, and I decided it'd be nice to write an object class system for objects that had to be held to be read (like a pamphlet) while still allowing for ones that don't (like a billboard).

More difficultly, I wanted to do this on the grammar level so all "You don't have that." messages didn't use up a turn.  Truthfully, it's not easy to have varied behavior when it comes to held/unheld verbs.  I knew that when I did get around to writing this system, I'd have to use my Roodylib "routine grammar helper" system.

I finally got around to looking at this problem yesterday.  It was one of those funny times where you return to an old problem a bit smarter and almost resent the obligation to improve your solution ("WHY CAN'T I JUST STAY STUPID FOREVER?").

First, to help me design the readable object classes, I looked over some grammar classes I had made previously for containers that are emptied in different ways (those that had to be held vs those that don't and so forth).  In my testing, though, the "empty" code wasn't working, and for a while there, I thought maybe I had broken FindObject somewhere along the way (and getting FindObject to do the things I already have it do was a scary, confusing journey so I wasn't looking forward to working on it again).

It turned out that a call to FindObject from AnythingTokenCheck (which itself is called from within FindObject) should have used the "recurse" argument.  Whew!

I also decided that half of my original "routine grammar helper" code was unnecessary.

But anyway, that's all working better now, although I might redesign the routine grammar helper again, possibly to use attributes instead of variable masking.

And, oh yeah, if you were curious, no, I don't think the Hugo Comp is happening.  That discussion fizzled out pretty quickly.

* * *

STATUSTYPE is a global variable that determines what kind of information is displayed in the upper right corner of the status window.  One of the several options displays a game clock like in the game Deadline.  Since the HoursMinutes routine used to print the time could also do military time, a while back, I added a STATUSTYPE value that provides a military time clock (like in Border Zone).   It kind of bugged me that the code didn't have an easy way to switch between the military time with colon and without.  While easy enough to provide a choice for the author, I really wanted it to be as unobtrusive as possible because, really, there's like no chance anyone is going to write a military time game again, and it'd just be embarrassing to show that I spent much time doing some sort of time-configuration system for a feature no one would ever use.  I ended up with just going with a #set NO_MILITARY_COLON flag.

* * *

There are a couple other things, but I'm getting tired of writing.  Anyway, probably will try to put out a Roodylib update within the next couple weeks and then maybe do a round of uploading-stuff-to-the-IF-archive.  Then, maybe, write some IF?  (gasp)

Friday, August 19, 2016

Summertime Frolicking

One of my favorite things about frolicking is how quickly I get sick of it and want to return to my projects.  That said, August is lousy with birthdays among my friends and family (of course, I mean that in the quantitative, Catcher in the Rye sense and not the qualitative one), and I've still got some pool parties, a "pedal tavern," and possibly a trip to the Renaissance Faire in my future.

Still, I can't wait to submerge myself in something Hugo again.  Earlier this week, I made some progress in my most recent problem; I had noticed how horribly broken the baby-naming code was in my silly, nonsensical game, "Baby Uncle New Year," and I wanted to fix it up.

I was hoping my new code would be general enough that I could easily throw it into Roodylib for everybody to use, but it ended up being too specifically purposed.  When I get back to coding, writing that general purpose system will probably be my next task.

Ideally, I'd like it to do these things:
  1.  If the game is being played on an interpreter that supports Hugo's timing system (and accessibility mode is not turned on), it would throw up a floating window like in my game "The Halloween Horror" and use my "fake prompt" code to capture the input and writing it straight to an array.
  2. If the game is being played on a glk interpreter or has accessibility mode turned on, it has a prompt in the main window.  Actual Hugo prompts are tricky because unless the text is within quotation marks, Hugo can only keep track of one unrecognized word.  I'll have to find a tactful way to instruct the player accordingly.
  3. Both of these will result in a, "'<blah>'? Is that correct?" response so the player can double-check how it was received.  Even with whatever nudging I give, the main window Hugo prompts have a fair possibility of being wrong, like if the player used any of the "removal" words ("a", "an", "the", "some", "of") that Hugo automatically drops from input lines.
  4. Include an option to write all unrecognized words to the game dictionary and apply them to an object.
At least one game in progress by another person uses my "fake prompt" code so I figure this system could be useful to others as well.  Besides this, I need to reacquaint myself with my Hugo "to do" list and see if there's anything else I'd like to add before the next Roodylib release.  I also have some real world research I want to do on one of my game ideas.

Here's to ending 2016 with a little more Hugo in the world!

Wednesday, July 27, 2016

some progress summer

Since the last post, I helped that friend with that problem (GAME'S LOOKING GOOD, JIZ) and made some Roodylib progress (fixed some bugs, redesigned some stuff, and incorporated one or two new extensions).  I have an out-of-town friend coming in this week, and I'd been meaning to recompile all of my old games with my default menu code and just try to make them look as consistent as possible.

I've actually been meaning to do this for years, but this friend really doesn't know anything about IF so I kept putting it off because I wanted the consistency between games to be perfect...  and honestly, I usually like to give a middle finger to perfection.  It's too damn  hard to finish projects in the first place.

Still, applying something like Roodylib to old code is always interesting.  It's getting to the point where the library application is a lot more seamless than it used to be, and I even found the culprit in my update to Christopher Tate's "converse" extension that was keeping it from working straight out of the box.  That's been irking me for years, but now that it's fixed, my version is just about ready for public release, I think.

Anyhow, despite all of that Roodylib work, I'm getting to the point where I feel I need to give more attention to my WIPs.  One disappointment was the reminder that all of them are missing some big mid-game chunk of design.  The plan is to sit down with some flowchart software one day and stare at the screen until inspiration strikes.

But hey, it's summer and the days are beautiful, so it's been hard to make IF a priority.  Have to enjoy these few months of sun and warmth that we get, so I'm trying to get out as much as possible.  Frolicking, even.

So much frolicking.

Tuesday, July 5, 2016

Roodylib 4.1.2

I'm several months late in helping someone code a scene in their game, so me being me, that means I went and got Roodylib ready for a new release!  SORRY, JIZ!

The three main elements of this new update are:

  • Incorporated the accessibility code mentioned one or two posts back into Roodylib and made them available by default.  I may add another accessibility feature at some point- some kind of spelling system for uncommon words (as discussed on the intfiction.org forums)
  • Code supporting Nikos Chantziaras' Hugor opcodes system
  • Incorporated "newmenu.h" into Roodylib so one doesn't have to include the extra file.  I added mouseclick support to menus sometime within the last handful of months, too.

Sunday, May 29, 2016

"sandbox" modes

After completing Michael Berlyn's Suspended, a player is given a special command that allows configuration of the main game- moving robots here and there, changing the timer, etc.  I heard about this feature many years before I actually beat Suspended.  At the time, it sounded like overkill for a game that I had bashed my head against (although in hindsight, it's really not the Herculean effort I thought it was).

I have to admit that, having beaten the game and finally being familiar with how things fit together, the extra challenge mode seemed like a cool idea.  Wow, a player could really make this game as hard or easy as they want to; I could see a fun optimization puzzle emerging.  I have to admit that I never actually played much with this extra mode, but it was cool to see and finally understand.

I've pondered nice ways to provide a similar experience for players, and the easiest answer I came up with was to give the player a magic word when the game is completed that turns on debugging mode.  They'd be able to look at the object tree, move objects or the player around, or even control how daemons run.  I thought this would be a fun way to share the innards of the game with the player; for some reason, having game source available doesn't provide the same thrill unless it's, say, in Hugo and I'm applying new Roodylib functionality to it or something for my own curiosity.

Today's code sample supplies this magic word debugging system.



Now I just need to write a game that players would want to dig into!

Saturday, May 28, 2016

general update and "bags of holding"

Some interesting news in Hugoville.  Nikos Chantziaras has added an opcode system to Hugor, allowing for some special behavior here and there.  Unfortunately, along with posting here about stuff more often, I've been meaning to update the Roodylib documentation to cover all of the new stuff and put out a new release.  So, more news down the road!

In the meantime, I thought I'd share some code examples I put together the other month; well, one now, one next time I write here.

Today's bit of code will be for what IF lingo calls a "bag of holding."  I'd say they were first popularized in late era commercial IF although they first showed up a bit earlier than that.  Players still had set carrying capacities so object-management was required, but one object in the game- usually a bag or knapsack- could carry a limitless number of objects.  As soon as you couldn't pick up anything more, you'd stick stuff in the bag of holding and, yay, looting can recommence!

Bags of holding got even cooler when the game would automatically stick stuff in them for you.  Today's code sample will be an automatic bag of holding system in Hugo.



Just set the bag_of_holding global to your bag of holding object, and there you go!  Now, admittedly, this system is pretty simple. It only allows for swapping one object that, when moved, will create enough space for the new object. I considered writing another pass if the first one didn't find a suitable most, but I figured that this behavior would fit most games.  If a game has large variance in object sizes, the large objects probably should get special treatment through before routines and such.  Plus, it's always kind of ugly when you try to pick something up and then half of your inventory is moved to the bag of holding so I didn't want to encourage that.

Monday, February 15, 2016

Announcing the Hugo Notepad++ add-on

Some people were unable to use my standalone Notepad++ package because they already had Notepad++ installed.  I finally got around to putting together a package adding (most of) its functionality.  Just download the following file and follow the instructions in the .pdf file!

https://drive.google.com/file/d/0B_4ZXs4Z_yoWclhaOFFYQ3JScjg/view?usp=sharing

It includes the compiler, an interpreter, and library files, so once installed, you'll be ready to start writing your Hugo game!  As mentioned in the .pdf, all of the new commands will be under the Macros tab when you're done.

Saturday, January 16, 2016

new ZIL blog

Just a quick note that I've started an additional blog where I'll write about my experience exploring ZIL, the language used to write the Infocom games:

ZIL Crazy After All These Years

Feel free to tag along!