Skip to content

Instantly share code, notes, and snippets.

@IFcoltransG
Last active January 4, 2024 01:31
Show Gist options
  • Save IFcoltransG/8e7594dc368e14676747bcefefe731de to your computer and use it in GitHub Desktop.
Save IFcoltransG/8e7594dc368e14676747bcefefe731de to your computer and use it in GitHub Desktop.
Inline "clickers" in Inkle's Ink, for choices that toggle a variable
// Ink clicker code created by IFcoltransG
// Released into public domain
// May be used under the MIT No Attribution License
LIST journey_soundtrack_songs = Nascence, Apotheosis, Reclamation
VAR a = Nascence
VAR b = Apotheosis
-> go
== go
Here's Box A: <-clicker("a", a, -> go)
. And here's Box B: <-clicker("b", b, -> go)
. You can change the contents of both below.
+ Commentary?
- The idea is that the [TEXT](ID) syntax will be used to define a hyperlink embedded in the text, that says "TEXT" and activates the choice tagged "\# id:ID" (which also shouldn't be displayed). So these clickers will display their current value, and you could click them to advance their state to the next state. The choice would take you to the same page as before, just with a new value in the clicker. That way you can click the link a few times to get the result you actually want.
It's inspired by the links in smwhr's Palazzo Heist game written in Porcelaine (Ink), and how they edit existing bodies of text. Also the Twine game Howling Dogs by Porpentine, which has links that contain adjectives, where clicking the link changes the adjective. It's also inspired by immediate-mode GUIs, specificially egui, which constantly recalculate what the UI should look like based on the current value of variables.
I'd love if A and B could be temp variables, but I get big stack problems if I try to stop them from being global variables. Well actually, you can make go take a and b as parameters (divert parameters aren't global) but then it's no longer as modular, because the screen displayed by \-> go can't change the number of clickers very easily without also changing how many values are passed to the \-> back() divert inside the clicker's code. So I think global variables are the least messy way to do this.
I'm thinking about turning the link processing into an engine for Ink — like Porcelaine. It's not that I don't like Porcelaine (which does most of this) but I'd like something that's more minimal, that doesn't create the extra buttons for options.
You could probably do a lot of interesting things with the \<- clicker_with_display_function() thread, like expandable menu spoilers. It's just like the normal clicker, but you also pass in a one-argument function that describes how to display each list value. You could have a LIST expanded_state = Open, Closed where the display function provides a long description if it's Open.
-> go
=== clicker(id, ref val, -> back)
<> [{val}]({id}) <>
+ Next item [#clicker #id:{id}]{wrap(val)}
-> back
- -> DONE
=== clicker_with_display_function(id, ref val, -> back, -> display)
<> [{display(val)}]({id}) <>
+ Next item [#clicker #id:{id}]{wrap(val)}
-> back
- -> DONE
=== function wrap(ref val)
{val + 1 == ():
~ val = LIST_MIN(LIST_ALL(val))
- else:
~ val += 1
}
@IFcoltransG
Copy link
Author

I've now learnt about Cycling Links in Twine, which I think is the underlying tech that does this in Twine games.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment