In a game that uses non-default text/background colors, UNDOing after a full-screen-color-change will result in "islands" of the old colors on a screen of the new backgound color. This works in contrast to systems like TADS where changing the background color can be done without clearing the screen. The way Hugo handles it is not necessarily a detriment; I have an idea for at least one game idea that wouldn't work if Hugo worked the other way.
Still, it introduces an interesting dilemma- is there a way for the library to handle such UNDO situations in a non-obnoxious manner? I've been thinking about this since yesterday.
Instead of trying to design some complicated word-array-saving technique to keep track of colors (as the word array is one of the only things not affected by UNDOs, RESTOREs, and RESTARTs), I eventually decided that the best way to handle this will be to write a configuration-file-writing library extension. All of the Hugo ports that I know of that support color also support configuration files, anyway.
The hardest part will be deciding what kind of naming scheme I want for the configuration file so it plays nicely with other games that use the same extension.
Anyhow, when it's written, it should be appreciated by color-lovers and color-haters alike (as it will also give players options to "opt out" of color changes).
Friday, June 29, 2012
Thursday, June 28, 2012
init thoughts and updates
First off, I spent a good chunk of time working on the glk update of Cardinal Teulbach's "automap" extension yesterday. It no longer requires "glk.h" and now has proper message routines. As I have done with some other extensions, I changed most of the global variables to object properties, as there is a hard limit on global variables and there isn't one on properties (plus, most of the time, you can alias your new property to some pre-existing propert). I don't know if Robb Sherwin ever ran into the global variable limit on Cryptozookeeper, but judging by the game source, I'd guess it has more than a hundred global variables (and the limit is 150), so it could be a limit that nobody ever runs into but I avoid it just the same.
The coolest addition to the automap extension actually involves adding a global variable, though. If you are using the "windows.h" header file and create a window with it, you can set the map_window global variable to that window. Then, every turn, it'll draw the map to that window. The intent is to make it easy to make a game with a Cryptozookeeper/Fallacy of Dawn type screen layout and be able to use one of the windows for an automapper.
The nice thing about touching up "automap" and "boxdraw" is that I think they are getting to the point where I can demote the original files to "outdated" status on Hugo by Example. I still don't know how likely it is that anyone will use them, but it should be simpler to approach from now on.
So yeah, the other thing, init.
Considering I want it to get to a point where an author doesn't really need to think about where to throw an extra routine into init, I've been thinking that the traditional order of things in init should be shaken up a bit.
As it is right now, global variables like "player" and "location" aren't set to nearly the end of the routine, after the intro and game title have already been printed. This makes it harder to find that sweet spot to call certain routines or start fuses that rely on those globals being set properly.
I intend to tidy things up so the order is something like this:
The coolest addition to the automap extension actually involves adding a global variable, though. If you are using the "windows.h" header file and create a window with it, you can set the map_window global variable to that window. Then, every turn, it'll draw the map to that window. The intent is to make it easy to make a game with a Cryptozookeeper/Fallacy of Dawn type screen layout and be able to use one of the windows for an automapper.
The nice thing about touching up "automap" and "boxdraw" is that I think they are getting to the point where I can demote the original files to "outdated" status on Hugo by Example. I still don't know how likely it is that anyone will use them, but it should be simpler to approach from now on.
So yeah, the other thing, init.
Considering I want it to get to a point where an author doesn't really need to think about where to throw an extra routine into init, I've been thinking that the traditional order of things in init should be shaken up a bit.
As it is right now, global variables like "player" and "location" aren't set to nearly the end of the routine, after the intro and game title have already been printed. This makes it harder to find that sweet spot to call certain routines or start fuses that rely on those globals being set properly.
I intend to tidy things up so the order is something like this:
- Screen-clearing code and the like so games look the same for new games or restarts.
- Set all global variables (including "player" and "location"
- Execute any routines-to-be-called by init (like those from library contributions)
- Print game intro and title
- execute MovePlayer(location)
Wednesday, June 27, 2012
Non-glk simple interpreter intros
Especially as I take another look at my glk code recently, I've also been looking over my support for regular "simple" Hugo ports. The only one I have at my disposal is the simple DOS interpreter. Despite the fact that, in this day and age, I wouldn't expect anyone to actually use it, I am shooting for a library extension that will look great on normal, glk, and simple terps without any messy code. That isn't to say that the simple interpreter isn't useful in its own way. Running your game through it is a good way to see if your game calls PrintStatusLine too many times per turn (as status windows in the simple DOS interpreter are a real eyesore), and beyond that, it can just be a good reminder of how stripped-down some interpreters out there might be.
Last night, I was looking into why a game beginning in the simple interpreter draw an extra status window regardless of whatever code you might have in init. Eventually, I decided that a window is drawn when the game begins, before init is even called. Admitting defeat on that issue, I think started thinking about how to make it look as cool as possible in the simple interpreter. Finally, I decided that it'd be cool to have some kind of ASCII logo or "loading screen" that'd give the feel of proper old-school DOS program. Here is a placeholder demonstration:
(The logo would go where it says "loading game"/"please wait".) Anyhow, if anyone has any logo or text suggestions, I'd be happy to throw them into my code!
EDIT: Conversely, I guess I could just print a bunch of blank lines until the empty status bar is off the screen. Made up a test and it works pretty well. Still, if someone gave me some cool ASCII art, don't think I won't put it in there!
Last night, I was looking into why a game beginning in the simple interpreter draw an extra status window regardless of whatever code you might have in init. Eventually, I decided that a window is drawn when the game begins, before init is even called. Admitting defeat on that issue, I think started thinking about how to make it look as cool as possible in the simple interpreter. Finally, I decided that it'd be cool to have some kind of ASCII logo or "loading screen" that'd give the feel of proper old-school DOS program. Here is a placeholder demonstration:
(The logo would go where it says "loading game"/"please wait".) Anyhow, if anyone has any logo or text suggestions, I'd be happy to throw them into my code!
EDIT: Conversely, I guess I could just print a bunch of blank lines until the empty status bar is off the screen. Made up a test and it works pretty well. Still, if someone gave me some cool ASCII art, don't think I won't put it in there!
Monday, June 25, 2012
DescribePlace musings
Tonight, I was working on my "Frankenstein monster" version of DescribePlace (http://hugo.gerynarsabode.org/index.php?title=Replace_DescribePlace). Beyond the things already listed by DescribePlace, I was thinking it'd be cool to add two additional configurable things to check, so conceivably, you could put one right after the room description to call routines like YouCanGo ("You can go east to the lake or north to the parking lot.") without having to edit each room's long_desc to call it. On the other end of the spectrum, you could call routines like score notifications or footnote stuff so they are printed after all room description stuff but before event/script stuff.
My test code was working great until I remembered that YouCanGo, my test routine, prints messages every time and that my code wasn't prepared for situations where something may or may not be printed (btw, sorry I'm so italics-intensive). To do proper spacing, there are parts of DescribePlace where one should only print a new line if something else is going to be printed, so it's important to know whether something will print before you call it. I tried to get around this uncertainty by using "text to <array>" to hide all text when the routine is called, using its return value to determine whether it was successful- and if so, running the routine again once I stopped writing to array. Unfortunately, even when writing to an array, carriage returns are processed normally, so there was no way to avoid ugly, extra space in my game.
Anyhow, I'm not really happy with my options at the moment. For the meantime, I'm throwing my whole idea to the backburner until I come up with something more appealing.
My test code was working great until I remembered that YouCanGo, my test routine, prints messages every time and that my code wasn't prepared for situations where something may or may not be printed (btw, sorry I'm so italics-intensive). To do proper spacing, there are parts of DescribePlace where one should only print a new line if something else is going to be printed, so it's important to know whether something will print before you call it. I tried to get around this uncertainty by using "text to <array>" to hide all text when the routine is called, using its return value to determine whether it was successful- and if so, running the routine again once I stopped writing to array. Unfortunately, even when writing to an array, carriage returns are processed normally, so there was no way to avoid ugly, extra space in my game.
Anyhow, I'm not really happy with my options at the moment. For the meantime, I'm throwing my whole idea to the backburner until I come up with something more appealing.
More glk.h talk and some init
I've been continuing going over my "glk.h"-using library contributions, as I consider "destroying" it. For some of them, changing glk-checks to a simple-port-check makes absolutely no difference, like for boxdraw (the quote-box drawing extension), as both glk and regular simple interpreters can't use the command "locate" in the main window. The automap extension will require a bit more attention, though, as "locate" does work in the status window (which allows me to redirect the map up there), but it won't work at all in regular simple ports (like the simple DOS port), where I'll have to disallow it completely.
Another thing on my mind is how we can improve handling of the "init" routine. Despite how relatively straightforward it is, I worry that it looks like a bunch of noise to a newcomer, so if possible, I'd like to figure out a good way to compress and modularize it. Ideally, I'd like to come up with a way where including a library contribution automatically adds relevant routine calls to init so adding extensions isn't always an exercise in editing init.
Actually, just this instant, I thought of a possible answer to that. I could make a init_routines object. Each library contribution, when included, will place an object (with a property pointing to the relevant setting-up routine) inside that init_routines object. Then init could just have a routine that checks for children of the init_routines object and executes all relevant properties. I could probably also add an order priority system if it turns out that order of execution really matters (of course, order will already be set by order of inclusion, too).
Well, at some point, I'll probably throw the above together as a proof-of-concept. Hopefully, it doesn't come across as needless obfuscation to everyone else!
Another thing on my mind is how we can improve handling of the "init" routine. Despite how relatively straightforward it is, I worry that it looks like a bunch of noise to a newcomer, so if possible, I'd like to figure out a good way to compress and modularize it. Ideally, I'd like to come up with a way where including a library contribution automatically adds relevant routine calls to init so adding extensions isn't always an exercise in editing init.
Actually, just this instant, I thought of a possible answer to that. I could make a init_routines object. Each library contribution, when included, will place an object (with a property pointing to the relevant setting-up routine) inside that init_routines object. Then init could just have a routine that checks for children of the init_routines object and executes all relevant properties. I could probably also add an order priority system if it turns out that order of execution really matters (of course, order will already be set by order of inclusion, too).
Well, at some point, I'll probably throw the above together as a proof-of-concept. Hopefully, it doesn't come across as needless obfuscation to everyone else!
Sunday, June 24, 2012
Roodylib, glk, and cheapglk
So I've been working on an extension for the standard library that I call "roodylib" (http://www.joltcountry.com/phpBB2/viewtopic.php?t=8324). Basically, it's a compilation of standard library routine updates and some utility routines I find useful enough to bundle with the library. I've been going over previous library contributions in search of things useful and lightweight enough to throw in.
Looking at my "newmenu.h" contribution prompted a bunch of additions and changes (not yet uploaded at the time of this post). It no longer requires "glk.h" to work well with glk interpreters. Likewise, the latest version of PrintStatusLine in "roodylib.h" also does some glk-detecting stuff (mainly for the purpose of detecting non-glk simple interpreters), also without the help of "glk.h".
The progress in these things has got me thinking two things. First off, I realized that my "glk.h" and "cheapglk.h" library contributions, being global-variable-based, will be broken if saved games are shared between different interpreters (although I'm not ever sure if Hugo save files are supposed to work between different interpreters). So, really, DoRestore should be replaced to re-detect glk-ness.
Secondly, I'm thinking I might move towards dropping a global variable for glk altogether. I'd add an "IsGlk" routine to "roodylib" and assume people will use it and modify "glk.h"-using library contributions to just call that routine.
Support for "cheapglk" interpreters (playing environments where status bars might not even be shown) is not even necessary now that the new GlkOte (http://www.eblong.com/zarf/glk/glkote.html), which has support for printing status bars in such environments.
Still, I'm thinking of keeping Hugo "cheapglk" support around, as my cheapglk alternatives cut down on unnecessary printed white space, which might be preferable under some circumstances. The difference is that instead of asking the player if they are using a "cheapglk" interpreter after detecting glk, I'm thinking of changing it to a mode that can be turned on and off from kind of interpreter.
Looking at my "newmenu.h" contribution prompted a bunch of additions and changes (not yet uploaded at the time of this post). It no longer requires "glk.h" to work well with glk interpreters. Likewise, the latest version of PrintStatusLine in "roodylib.h" also does some glk-detecting stuff (mainly for the purpose of detecting non-glk simple interpreters), also without the help of "glk.h".
The progress in these things has got me thinking two things. First off, I realized that my "glk.h" and "cheapglk.h" library contributions, being global-variable-based, will be broken if saved games are shared between different interpreters (although I'm not ever sure if Hugo save files are supposed to work between different interpreters). So, really, DoRestore should be replaced to re-detect glk-ness.
Secondly, I'm thinking I might move towards dropping a global variable for glk altogether. I'd add an "IsGlk" routine to "roodylib" and assume people will use it and modify "glk.h"-using library contributions to just call that routine.
Support for "cheapglk" interpreters (playing environments where status bars might not even be shown) is not even necessary now that the new GlkOte (http://www.eblong.com/zarf/glk/glkote.html), which has support for printing status bars in such environments.
Still, I'm thinking of keeping Hugo "cheapglk" support around, as my cheapglk alternatives cut down on unnecessary printed white space, which might be preferable under some circumstances. The difference is that instead of asking the player if they are using a "cheapglk" interpreter after detecting glk, I'm thinking of changing it to a mode that can be turned on and off from kind of interpreter.
What This Blog is About
I can't see where, if possible, to describe what this blog's emphasis is, so I will use this first post to do it here. Anyhow, this blog will be my "thinking sandbox" for Hugo design, where Hugo is the interactive fiction system created by Kent Tessman (http://www.generalcoffee.com/hugo/gethugo.html).
I recently found out that Hugo got its name from an early script by Kent entitled "Dead Hugo" (he's also a filmmaker- check out his screenwriting program: http://www.fadeinpro.com/ ). I thought it'd be funny to choose a name that points out that Hugo, the language, is not dead, but the phrasing is just odd enough that it could be interpreted several ways.
Anyhow, other Hugo enthusiasts are highly encouraged to weigh in on any of my speculations. Let's see how this thing goes.
I recently found out that Hugo got its name from an early script by Kent entitled "Dead Hugo" (he's also a filmmaker- check out his screenwriting program: http://www.fadeinpro.com/ ). I thought it'd be funny to choose a name that points out that Hugo, the language, is not dead, but the phrasing is just odd enough that it could be interpreted several ways.
Anyhow, other Hugo enthusiasts are highly encouraged to weigh in on any of my speculations. Let's see how this thing goes.
Subscribe to:
Posts (Atom)