As mentioned elsewhere, I’m currently toying with something akin to The Impossible Bottle’s hyperlink interface. It seems like such a great way to play IF on a touchscreen, and I want to experiment with it and see what directions it can be taken in.
Here’s the current plan:
Draw an inline status area every time the status bar is updated.
(redraw status bar) %% Overridden to also handle the inline bar
(status bar @status) {
(exhaust) *(status element)
}
(if) (link bar enabled) ~(opening cutscene) (then) %% For this game, disable it during the opening cutscene too
(par)
(inline status bar @inlinebar) {
(exhaust) *(inline status element)
}
(endif)
(link bar enabled)
lets players turn this off if it gets annoying.
Then, we can write whatever rules we want for (inline status element)
to put them in this bar. For example, we always show LOOK, so that we’re not leaving an empty bar.
(inline status element) %% First, the obvious exits
(link) {look}
(current room $Room)
(exhaust) {
*(from $Room go $Dir to $Target)
(direction $Dir)
(if) (door $Target) (or) (room $Target) (then)
(bullet) (link) (name $Dir)
(endif)
}
The way the Impossible Bottle one works, clicking on a noun in the text examines it, via the library’s built-in default actions system. But once you’ve examined it, you can see other verbs to try on it.
(global variable (last named object $)) %% Need to modify (notice player's $) and (forget pronouns out of scope) to update this
(inline status element) %% Then, the most recently named object
(last named object $Obj)
\| (link) (the $Obj)
(exhaust) *(link viable actions for $Obj)
And in this game, you can only hold one thing at a time, so we can put the held object in the bar too.
(inline status element) %% Finally, anything we're currently holding
(held $Obj)
~(last named object $Obj)
\| (link) (the $Obj)
(exhaust) *(link viable actions for $Obj)
(held $Obj)
(current player $Player)
($Obj is #heldby $Player)
Now, Impossible Bottle I believe used the pronoun values instead of tracking a single last named object, which means TAKE IT and such are viable ways to phrase the command. But I don’t want to risk bugs when the last named object and the pronouns get out of sync, especially since I don’t fully understand the difference between “player’s it” and “narrator’s it”.
So, a convenience predicate to phrase our links nicely:
(link action $Action with $Obj) %% [take $] #apple -> take apple, take it
(collect words)
(the $Obj)
(into $Noun)
(collect words)
(them $Obj)
(into $Pronoun)
(splice list $Noun into $Action to make $Link)
(splice list $Pronoun into $Action to make $Text)
(fully bound $Text) %% Avoid compiler warnings
(bullet) (link $Link) (print words $Text)
And the helper to make it work:
%% splice list [b c] into [a $ d] to make [a b c d]
(splice list $Inner into [(bound $Head) | $Tail] to make [$Head | $NewTail])
(splice list $Inner into $Tail to make $NewTail)
(splice list $Inner into [$ | $Tail] to make $Out)
(append $Inner $Tail $Out)
Now we can have a whole bunch of rules like this, to present the different actions:
(link viable actions for $Obj)
(item $Obj)
~(held $Obj)
(link action [take $] with $Obj)
So far, the actions I’ve included are:
- If item and not held, TAKE $
- If held, DROP $
- If held and edible, EAT $
- If actor container or actor supporter, ENTER $ or CLIMB $
- If openable, OPEN $ or CLOSE $
- If switchable, SWITCH $ ON or SWITCH $ OFF
- If container or supporter, SEARCH $
- If accepting objects behind or under, LOOK BEHIND/UNDER $
- If pushable, PUSH $
- If held and another person is visible, GIVE $
And the especially complicated one:
(link viable actions for $Obj) %% This is the complicated one: PUT
(held $Obj)
%% We need to duplicate some work from (link action $ with $) here
(collect words)
(the $Obj)
(into $Noun)
(collect words)
(them $Obj)
(into $Pronoun)
(splice list $Noun into [put $ on] to make $OnLink)
(splice list $Pronoun into [put $ on] to make $OnText)
(fully bound $OnText)
(bullet) (link $OnLink) (print words $OnText)
\(
(splice list $Noun into [put $ in] to make $InLink)
(link $InLink) in
,
(splice list $Noun into [put $ under] to make $UnderLink)
(link $UnderLink) under
,
(splice list $Noun into [put $ behind] to make $BehindLink)
(link $BehindLink) behind
\) something
Which makes a link like “put it in (on, under, behind) something” that links to PUT $ IN, PUT $ UNDER, etc.
How is this looking so far? Any horrible coding practices that’ll bite me in the back later, or design decisions that are a bad idea to start with? Or things that you think would improve the final product a lot?