Friday, February 10, 2017

AXMA Story Maker 5

I've long been a fan of AXMA Story Maker, a Russian-developed hypertext choice narrative engine that is very similar to Twine. I used an early version to write Devil's Food, a speed-Ectocomp entry in three hours. AXMA is now up to version 5, and despite its relative obscurity with English-speaking IF authors, there's a whole lot here to like. AXMA offers an easy alternative for those who want to write a choice-narrative, but, like me, may find Twine's nearly unlimited modifiable adaptability a little bewildering.

First off, AXMA is technically a free app with a "professional version" that lists for €29.90 via PayPal (but as of this writing is marked down to €19.90, approximately $22 USD) which is not a bad deal. The free version is unlimited to use, disabling only direct HTML export (all games can be uploaded to and are hosted by AXMA's public library for online play or download). Upgrading for the one-time fee doesn't change the software, but unlocks the ability to export HTML directly, as well as allowing the author to modify the resulting HTML file, and removes a "created with AXMA Story Maker" link on the title screen.

I've described AXMA to some people as "imagine if Steve Jobs had designed Twine"; AXMA is a closed-system so it's not as modifiable as Twine, but what's included is very powerful and provides enough functionality most authors will want. Saving, restoring, modifying text size and toggling game audio is accessed by an icon and/or a right-click.

AXMA's standard right click dialog

Every game displays beautifully on desktop and mobile (!) screens with no modifications necessary. That means that the game interface elements are structurally uniform in any game, but can be modified with several themes, and tweaked with regard to background, border thickness, colors, and about five fonts (basically variations of serif, sans-serif, and Courier, limited but all readable). The overall interface layout can be chosen when a new game is created, which essentially changes the ratio of screen elements; "Interactive Fiction" makes the text window big and the constant graphic window and menu box share space as a sidebar. "Visual Novel" fills the screen with a graphic and makes text type out letter by letter and fully appear with a click like a JRPG, "Classic quest or RPG" prioritizes the screen picture (for a map or a location picture) with a smaller text box at the bottom and a long menu box on the side for stats. CYOA book briefly displays a big picture which then recedes to show just a single window of text. "Interactive Audiobook" is something I've never seen but presents interesting possibilities. The system is so flexible that I would use it to create documentation manuals and other instructional material that isn't IF. AXMA's own documentation is created with it.

Visual interface, there is also an option to view plain source code if you prefer.

If you've used old-school Twine, you probably will grok AXMA's markup almost immediately. You've got [[links]] and [[text to display|to go to this link]] and [[click this link|to go to this passage and change this {$variable = 2}]]. Links can be [[inline with the text]], and bare links on their own line are converted to nifty buttons automatically. The main interface shows passages that can be dragged and dropped with arrows connecting them, and there are shortcut keys for most useful functions. There is a permanent "StoryMenu" passage which can be filled with links that will always display in a sidebar menu—a function (along with permanent location-graphic window) that is a tricky feat in most interactive fiction systems that is built in here.

Byooottiful player interface...

One of the coolest features is that passages which just add flavor text, such as an inline link that solely provides information, can be formatted to actually appear over the current window instead of changing the text and requiring a "back" button to return to the story.

Brilliant.

AXMA is crazy happy to handle your multimedia. Images can be placed inline with the text, or sent to the "main picture" box, wherever it is formatted by the originally chosen layout. Graphics can even be defined as sprites, so ostensibly you could make a picture of a treasure whoosh out at a player, or move a marker around on a static map, or slide your characters into and out of a visual novel scene. AXMA differentiates between "music", which is played constantly in the background and loops until changed or stopped via a macro, and "sound effects" which are played once on a different channel from the music. Videos from YouTube and Vimeo can also be streamed within a passage. All media can be streamed from the internet, or provided locally in a folder with the game.



On iPhone
Works on mobile
Overall this is a polished package for hypertext and choice-based fiction. The only slight bumpy spots I've encountered: the documentation lists everything AXMA can do, but is not comprehensive, leaving some nuances to be discovered through experimentation. There is a Google group for English-language discussion that isn't very active, but I've had very good luck with getting the devs to respond, usually within a day. Otherwise, I've used web-page translation of the Russian forums, but otherwise, there aren't many other places to read up on what people are doing with this software. AXMA's online library, at least on the English side, is a bit of a mess with many unfinished experiments (and a few works of dicey NSFW subject matter), but stories from the free version of the software can be hosted there (there is a limit on how much multimedia can be included) and linked to directly as below.

Catch the Spy, one of the more impressive examples in the library.

AXMA Story Maker can be downloaded for PC, Mac, and Linux, and there is an in-browser editor online as well.

UPDATE: I purchased the software (actually a lifetime "Professional" account) via PayPal, and received my registration key via email promptly within 24 hours as promised on the site. The actual registration key is for earlier versions of ASM which work fully offline. The current version asks you to sign into your user account using the email and password you register on their website and will handshake that account online to unlock all features when using the standalone editor. AXMA Story Maker is a popular engine in the Russian IF community and is actively supported and distributed.
----
My IF can be found on IFDB, or via flashy links there from my website.





Monday, February 6, 2017

Undiscovered Bugs

Someone on the forums with the handle "lister" decided to industriously tag all the IFComp games on IFDB, so of course, I vainly searched to see where mine had placed over time. Finally on about page seven of hundreds of games, Transparent showed up. I gave it a play-through since I hadn't looked at it in a while, amazed at how packed with stuff it is. Who knows how I got it done; it was way too large for IFComp, and despite starting out moderately-scoped in my head, it blew up out of proportion and I didn't have time to test it as thoroughly as one would want.

As I explored Thorne Manor again, enjoying how well the random sound generation actually worked out, I couldn't remember what clever refusal message I had implemented if someone tries to pick up the bathtub:
>TAKE TUB
Taken.
Dammit.

With all the poorly-conceived inventory limits I had initially put in that game, my photographer was now walking around a haunted house carrying an entire claw-foot bathtub with shower and curtain. Luckily I had restricted objects that could be put in the PC's coat pocket with an adjective, so I was spared that ridiculousness, and I kept it in inventory since I didn't want to see if the butler would dutifully tidy it up and shut it in the hall closet. I solicited a lot of feedback post-comp from experienced beta testers, and nobody (including me) had ever caught this very easily fixed bug.

So what's the longest a bug has gone undocumented in a game? Comment below and tell me about the glitch you found years later in an old Comp entry or that one bit of weirdness that the Infocom team totally missed. Or anything obscure and hilarious that crops up when an IF is abused beyond what the author considered.


Friday, December 9, 2016

Fair Postmortem Available

I was exceedingly thrilled for my IFComp entry Fair to place 7th this year (woo! top 10!). I have finally written a postmortem which is posted on my blog. Since it's exceedingly long and spoilery, I chose not to push the entirety of it to Planet IF. You can read it here. Please leave comments if there are any other questions you have or elements of the game you'd like to hear about in more detail. Thanks to everyone who played the game and voted!

FAIR - Postmortem

After last year's Comp, and writing two ambitious games that nobody saw the back half of, I swore that I'd design my next game so that everyone would get to the ending. I'd build it slick like a water slide so people couldn't get stuck if they tried. My brain came up with "explore a tiny space, then answer a multiple choice question about it." There would be no wrong answer, and no puzzles along the way to hinder the player. The game would make no judgement and the player would be free to interpret the situation however they wanted. I also decided the setting would be much more mundane, not horror, more "indie-film bittersweet" and maybe character-based since I'd based all three previous games on situations and mechanics with little regard for anything else. At first in my initial frustration I had intended to troll the Comp hard in the manner of "This is what you want? Here you go!" I also toyed with satirizing the comp with some sort of pie-judging contest where all the flavors of fifty subsequent pies would be randomized and eventually all start to blend together where the player would get bored and just pick one randomly. Fortunately my frustration softened, and I realized I might actually be able to write this and make it somehow about the frustrating process of creating something and having it judged by people whose whims are fickle.

Thursday, August 4, 2016

Another Rulebook Post (Inform 7)

I wrote last week about getting over the fear of rulebooks in Inform 7, specifically by not using the all-powerful INSTEAD to accomplish everything.  After I read over the post, I remembered one of my specific hangups using rulebooks occurred because I was over-thinking the process: how does Inform know how my additional rules work in order?  How does Inform know what order the rules should go in? Don't I need to write them very specifically so Inform and the compiler don't get confused?

The short answer is not really.  Beyond a few minor sequencing points when polishing the text output, Inform does not care where in the source text we write our rules. And the rulebooks consider every rule in them unless a rule explicitly tells it to stop (with an INSTEAD or "stop the action.")

Imagine creating a shopping list. Unless we're extremely familiar with the grocery store layout, we'll write a list as items occur to us, possibly over a period of time or several days. We might make a little effort grouping frozen foods and produce together since we know they are in the same general area within the building, but as we shop, we're going to run down the list in each location. And theoretically without any specific handling issues, the items in our cart will stack so that the last thing we inserted into it will be the first thing checked out by the cashier, unless we decide to bump something onto the conveyor belt first, perhaps because it's heavy or frozen.

Remember that the source text is only feeding information to the compiler which arranges it for its own use. Any BEFORE rule you write goes into the Before rulebook, and all "before" rules will run before any CHECK rules.  In many cases it doesn't matter what order the rules run in; if the player cannot pick up a boulder for one reason, it doesn't matter whether they also can't pick it up for another reason.

In general, we are encouraged to avoid player messages until the REPORT stage after everything is happened. Sometimes it's nice though to give the player some feedback along the way, such as if the author/parser has taken a shortcut action for them, or to explain why an action failed.

Gauntlets of Hercules is carried by the player. It is wearable. A golden fleece is carried by the player.

some river sticks is a thing. 

Rocky Valley is a room. 

A giant boulder is in Rocky Valley. "A giant boulder here blocks the way north.". The description is "The boulder is taller than you, and more than likely not movable by mortal means." 

Check taking giant boulder (this is the really it's more awkward than heavy rule):
  if the player does not wear the gauntlets of Hercules:
    say "Shyeah, right. You're just going to pick that     boulder up and carry it with you. Har!" instead.

Before taking giant boulder:
  if the player wears gauntlets of Hercules:
    if giant boulder is not handled:
      say "You wiggle your fingers in the gauntlets given to you by the mysterious old lady. You hope she wasn't having you on about their magic powers." 

Before taking giant boulder (this is the can't carry anything and the boulder rule):
  if the player carries something:
    say "(first dropping everything else you're holding: [a list of things carried by the player].)[paragraph break]";
    now everything carried by the player is in the location. 
Carry out taking giant boulder:  if river sticks is off-stage:    now river sticks is in the location;    say "Some sticks weathered by the river are dislodged from the side of the boulder as you lift it."
Carry out taking giant boulder (this is the hard work requires loud noises rule):
  if giant boulder is not handled:
    say "HUUUERRRRRGHHHH--hey, it's not that heavy after all and you needn't have made such a noise before lifting it." 


Report taking giant boulder:
  say "You've got the boulder, but it takes both of your arms, and you won't be able to carry anything else. It's more awkward than it is heavy." 

Check taking something when the player carries giant boulder:
  say "If you reach for [the noun], you'll need to put down the boulder first." instead.
I defined these rules completely out of order as far as the actual logical sequence this would all occur in, but let's try it:

Rocky Valley
A giant boulder here blocks the way north.

>take boulder
(first dropping everything else you're holding: Gauntlets of Hercules, a golden fleece.)

Shyeah, right.  You're just going to pick that boulder up and carry it with you.  Har!

Hmn.  That technically worked, but it didn't make a lot of sense to make the player drop everything when they aren't even going to be able to actually lift the giant boulder. Let's specify the rule order a bit. I want the snarky message to be the only thing the player sees if they aren't wearing the gauntlets. That rule already ends with INSTEAD so let's tell Inform to put it "first" in the Check Taking* rulebook. 

First check taking giant boulder (this is the really it's more awkward than heavy rule):
if the player does not wear the gauntlets of Hercules:
say "Shyeah, right.  You're just going to pick that boulder up and carry it with you.  Har!" instead.

That way, any other rules I think of and write later, even in the future, won't even be considered until the player is wearing the gauntlets.

I also need to change my "can't carry stuff and the boulder" rule since it's a BEFORE rule that will always occur before a CHECK rule.  It actually makes more sense as CARRY OUT since there's no reason for the player to drop everything until they are actually going to lift the boulder. I will also tell Inform to put that "first" in the CARRY OUT rulebook since I don't want the player to make their mighty grunt and then decide they have to drop everything they have in their hands:

First carry out taking giant boulder (this is the can't carry anything and the boulder rule):
  if the player carries something:
  say "(first dropping everything else you're holding: [a list of things carried by the player].)[paragraph break]";
    now everything carried by the player is in the location.


Rocky Valley
A giant boulder here blocks the way north.

>take boulder
Shyeah, right.  You're just going to pick that boulder up and carry it with you.  Har!

There, that's much better. Continuing...

>wear gauntlets
You put on Gauntlets of Hercules.

>take boulder
You wiggle your fingers in the gauntlets given to you by the mysterious old lady. You hope she wasn't having you on about their magic powers.

(first dropping everything else you're holding: a golden fleece.)

Some sticks weathered by the river are dislodged from the side of the boulder as you lift it.

HUUUERRRRRGHHHH--hey, it's not that heavy after all and you needn't have made such a noise before lifting it.

You've got the boulder, but it takes both of your arms, and you won't be able to carry anything else. It's more awkward than it is heavy.

Taken.

>take fleece
If you reach for the golden fleece, you'll need to put down the boulder first.

>drop boulder
Dropped.

>take fleece

Taken.

Once again, that worked, but we'd like the text of the player grunting to happen before they lift the boulder and reveal the very important river sticks they will need later.  Once again, we tell Inform what rule should come first:

First carry out taking giant boulder (this is the hard work requires loud noises rule):
if giant boulder is not handled:
say "HUUUERRRRRGHHHH--hey, it's not that heavy after all and you needn't have made such a noise before lifting it." 

>wear gauntlets
You put on Gauntlets of Hercules.

>take boulder
You wiggle your fingers in the gauntlets given to you by the mysterious old lady. You hope she wasn't having you on about their magic powers.

HUUUERRRRRGHHHH--hey, it's not that heavy after all and you needn't have made such a noise before lifting it.

(first dropping everything else you're holding: a golden fleece.)

Some sticks weathered by the river are dislodged from the side of the boulder as you lift it.

You've got the boulder, but it takes both of your arms, and you won't be able to carry anything else. It's more awkward than it is heavy.

Still not quite right.  The grunt happened, but then the player doesn't drop everything until after that, which is still the wrong order.  Let's check the source text:

First carry out taking giant boulder (this is the can't carry anything and the boulder rule):
if the player carries something:
say "(first dropping everything else you're holding: [a list of things carried by the player].)[paragraph break]";
now everything carried by the player is in the location.
Carry out taking giant boulder:  
if river sticks is off-stage:    
now river sticks is in the location;    
say "Some sticks weathered by the river are dislodged from the side of the boulder as you lift it."
First carry out taking giant boulder (this is the hard work requires loud noises rule):
if giant boulder is not handled:
say "HUUUERRRRRGHHHH--hey, it's not that heavy after all and you needn't have made such a noise before lifting it." 

So we've defined two "first" rules. What's happened here is reliant on source text order.  We told Inform to put the "can't carry anything and the giant boulder" rule first, which it did.  Then we told it to put the "hard work requires loud noises" rule first also.  Since our previous rule is already the first rule in the rulebook, it is bumped forward a step to make room and let the other be first.

One solution is to switch the order of the rules in the source text.  However, if we write any other rules affecting the boulder later they might get out of order again. The other way is just to combine them into the same rule so they run in correct order as a unit:

First carry out taking giant boulder (this is the drop everything before heaving the boulder rule):
if the player carries something:
say "(first dropping everything else you're holding: [a list of things carried by the player].)[paragraph break]";
now everything carried by the player is in the location;
if giant boulder is not handled:
say "HUUUERRRRRGHHHH--hey, it's not that heavy after all and you needn't have made such a noise before lifting it."

For good measure, we can make sure our message about river sticks runs "last".

Last carry out taking giant boulder:  
if river sticks is off-stage:    
now river sticks is in the location;    
say "Some sticks weathered by the river are dislodged from the side of the boulder as you lift it."

>take boulder
Shyeah, right.  You're just going to pick that boulder up and carry it with you.  Har!

>wear gauntlets
You put on Gauntlets of Hercules.

>take boulder
You wiggle your fingers in the gauntlets given to you by the mysterious old lady. You hope she wasn't having you on about their magic powers.

(first dropping everything else you're holding: a golden fleece.)

HUUUERRRRRGHHHH--hey, it's not that heavy after all and you needn't have made such a noise before lifting it.

Some sticks weathered by the river are dislodged from the side of the boulder as you lift it.

You've got the boulder, but it takes both of your arms, and you won't be able to carry anything else. It's more awkward than it is heavy.

Taken.

Almost there.  We want to get rid of that "Taken" message which is the standard report taking response.  We can do that by changing our report taking giant boulder rule to an "after" taking giant boulder rule.  AFTER rules occur before report rules, and will naturally stop and override them (unless appended with "continue the action).

After taking giant boulder:
say "You've got the boulder, but it takes both of your arms, and you won't be able to carry anything else. It's more awkward than it is heavy." 

HUUUERRRRRGHHHH--hey, it's not that heavy after all and you needn't have made such a noise before lifting it.

Some sticks weathered by the river are dislodged from the side of the boulder as you lift it.

You've got the boulder, but it takes both of your arms, and you won't be able to carry anything else. It's more awkward than it is heavy.

>

As things get more complicated, it is actually possible to create a specific rulebook for a complicated action--say a magic box that transforms items into other items.  For this type of information, it's best to read the entire section about rulebooks in the Inform documentation.  There are also many more useful rulebooks beyond what I've only scratched the surface of here.


---

Thursday, July 28, 2016

Instead of Instead (Inform 7)

Inform 7 allows an author to accomplish things in many different ways.  It's easy enough to make a dungeon full of rooms and doors and containers and treasures, but if we go much further beyond that, we have to work with creating rules.

All actions in Inform have rulebooks which roughly correspond to phases of time it takes to perform the action.  The major three are

  • CHECK - This is where Inform decides if an action can be accomplished.
  • CARRY OUT - This is where the actual mechanics of the action take place.
  • REPORT - After everything is done, this is where the parser can print a message confirming what has taken place.
Three other rulebooks are built-in:
  • BEFORE
  • AFTER 
  • INSTEAD

BEFORE and AFTER slot where you'd expect, but INSTEAD is probably the most powerful and most mis-used due to that inherent power.  New authors often find the check/carry out/report sequence confusing at first, and will latch onto INSTEAD like Dr. Who's sonic screwdriver to accomplish everything. Why learn a whole handful of rulebooks when you only need one?

The reason is INSTEAD essentially is an override that relinquishes the parsing of a command over to the author. When one tells Inform "Instead of doing this action..." the parser won't bother checking anything and will use the author's specific rule.  Also INSTEAD overrides every other rule including other INSTEAD rules, defaulting to the most specific for a situation.

Suppose all flowers cause wooziness, but certain types have added effects:
Garden is a room.
A flower is a kind of edible thing.  A rose is a kind of flower.  A daisy is a kind of flower.  A lily is a kind of flower.  Understand "flower" as a flower.
There are four roses in garden.  There are six daisies in garden.  There are three lilies in garden. 
Instead of eating a flower: say "It tastes bitter and you feel woozy." 
Instead of eating a rose: say "The rosy scent tickles your nose."
Instead of eating a daisy: say "You feel light-headed."


Garden
You can see four roses, six daisies and three lilies here.
>eat flower
Which do you mean, a rose, a daisy or a lily?
>lily
It tastes bitter and you feel woozy.
>eat rose
The rosy scent tickles your nose.
>eat daisy
You feel light-headed.
>l
Garden
You can see four roses, six daisies and three lilies here.


You'll notice we aren't getting the default message for "flowers" in every case because the more specific Instead rule for roses and daisies override since they are more specific. Also problematic is that even though flowers are declared "edible" they aren't disappearing like standard edible objects because Inform has relinquished control to the author, and our INSTEAD rule doesn't handle the behavior for edible objects. So lets make this change:
Instead of eating a flower:
   say "It tastes bitter and you feel woozy.";
   remove the noun from play.
Garden
You can see four roses, six daisies and three lilies here.
>eat lily
It tastes bitter and you feel woozy.
>look
Garden
You can see four roses, six daisies and two lilies here.
>eat rose
The rosy scent tickles your nose.
>look
Garden
You can see four roses, six daisies and two lilies here.
So our INSTEAD with included eating rules is only working on lilies, which don't have more specific Instead rules affecting them. An enterprising new author usually here will go "No problem, I can write this into every instead rule."  But over the course of even a moderate-sized game this will grow tedious--especially if we want to write other rules that affect flowers, and we'll have to keep up and update every single rule:
Sickness is a number that varies.
Instead of eating a flower:
say "It tastes bitter and makes you feel woozy.";
increase sickness by one;
if sickness is greater than one:
say "You don't feel so good after that meal.";
if sickness is greater than two:
end the story saying "Flowers, while beautiful, have their downsides.  You have been poisoned!"

Instead of eating a rose:
say "It tastes bitter and makes you feel woozy.";
say "The rosy scent tickles your nose.";
increase sickness by one;
if sickness is greater than one:
say "You don't feel so good after that meal.";
if sickness is greater than two:
end the story saying "Flowers, while beautiful, have their downsides.  You have been poisoned!"

Instead of eating a daisy:
say "It tastes bitter and makes you feel woozy.";
say "You feel light headed.";
increase sickness by one;
if sickness is greater than one:
say "You don't feel so good after that meal.";
if sickness is greater than two:
end the story saying "Flowers, while beautiful, have their downsides.  You have been poisoned!"

The author is doing more work than they need to bypassing the parser with INSTEAD. Say we want flowers to eventually poison the player.  Every rule would need to do the work of the parser. While the before/check/carry out/report/after sequence of rulebooks seems daunting, it actually makes life easier:
Garden is a room.
A flower is a kind of edible thing.  A rose is a kind of flower.  A daisy is a kind of flower.  A lily is a kind of flower.  Understand "flower" as a flower. 
Sickness is a number that varies. 
There are four roses in garden.  There are six daisies in garden.  There are three lilies in garden.
After eating a flower: [AFTER will override the normal "You eat the thing. Not bad." report message for edible things]
say "It tastes bitter and makes you feel woozy."; 
First after eating a rose: ["First after" puts this message at the beginning of the After rulebook]
say "The rosy scent tickles your nose.";
continue the action. [So both messages will print as an AFTER will normally stop] 
First after eating a daisy:
say "You feel light-headed.";
continue the action. 
[It's good to name your rules]
Carry out eating a flower (this is the flowers are poisonous rule):
increase sickness by one.
 [An author needn't pack everything into a single rule.]
Carry out eating a flower (this is the consequences of eating flowers rule):
if sickness is greater than one:
say "You don't feel so good after that meal...";
if sickness is greater than two:
end the story saying "Flowers, while beautiful, have their downsides.  You have been poisoned!";
Garden
You can see four roses, six daisies and three lilies here.
>eat lily
(first taking the lily)
It tastes bitter and makes you feel woozy.
>l
Garden
You can see four roses, six daisies and two lilies here.
>eat daisy
(first taking the daisy)
You don't feel so good after that meal...
You feel light-headed.
It tastes bitter and makes you feel woozy.
>look
Garden
You can see four roses, five daisies and two lilies here.
>eat rose
(first taking the rose)
You don't feel so good after that meal...


    *** Flowers, while beautiful, have their downsides.  You have been poisoned! ***
 
INSTEAD rules are very powerful and good for limiting the player from doing foolish things or tying up loose ends of standard responses:
Instead of jumping, say "Out, damned spot!"
Instead of smelling, say "Your sinuses have been acting up, so that sense is currently nonfunctional for the time being." 

And even this type of power can be safely folded into the CHECK rulebook for the specific action:
Check eating a flower (this is the great power equals great responsibility rule): say "You shouldn't be eating flowers. Who knows if they are poisonous?" instead
-----
Thanks to the tireless denizens of the IntFiction.org forums where great advice for programming IF in Inform 7 is best obtained.  I have a website http://hanonondricek.wixsite.com/pyramidif









Wednesday, July 20, 2016

I am the Baker of Shireton/And I bake bread because baking is fun...

Now to find Bob the Hobo...
So I made a loaf of bread last night and...hunh.  How did that get in there?  It must have been that other version of me stashed in the back room...
















(I added some space so this doesn't crash with the preceding article on Planet IF)