Hi folks!
I've had this story sitting on my hard disk for years now, and never got around to doing the code for it. I'm pretty sure the code will be a PITA to work with; so I wondered if I could run the algorithm past a few pairs of eyes first; so I'm not throwing a whole lot of time into something with flaws that I've overlooked.
I've got a file format I've been using with the intention of writing the code to go with it later. It would be designed to output a Kindle book, with all the options being internal links.
In ePub, I can include javascript code to handle flags and simple variables. (variables would be strictly bounded; for example I have one var where there's a check [[if dd>3]] a check elsewhere [[if dd<5]]. As the variable is only ever incremented, its only valid values are 0, 1, 2, 3, 4, and 5+)
In the Kindle file format, there's no way of scripting. So I was thinking I could duplicate the pages. Foe example, if I have a variable that goes 0 to 3, and two flags, the script would create a set of "alternates":
That basically creates 16 copies of every page in the book. If I use something like [[random red|green|blue]]
in a page, each of these copies would get one allocated at random.
So a page which increases a variable or sets a flag wouldn't need to set a variable - if Page3 increments the variable, then Page3-false-false-0
would have a link that points to Page4-false-false-1
; and similar for the flags.
After creating all these pages, I can go through removing them again. Pseudocode:
numpages = 0
while (numpages <> total number of variants) {
numpages = total number of variants
for each page {
for each variant {
If no pages link here:
remove this variant
}
}
}
numpages = 0
while (numpages <> total number of variants) {
numpages = total number of variants
for each page {
for each possible combination of the values for vars used in [[if]] blocks on this page {
outputpages = new array
for each variant {
make a list of the output pages that it links to (a string like "Page3-false-false-0/Page4-false-false-0")
if this string is in the "outputpages" list:
remove this variant
Loop over all pages that link to this variant:
change them to point to the previous one that had the same outputs
otherwise:
add the string to the "outputpages" list
}
}
}
}
The first loop removes pages like Page1-true-true-1
- because you can't have those flags set before reaching the first page. If it's removed any pages, it needs to run again to remove the pages that they link to. This should cut out a lot of the different pages.
The second loop: The "output pages" for any "The End" page will be the same: a "Try again" link back to Page1-false-false-0
.
So that means that if Page23 is a game over, all links to Page23 will be changed to point to Page23-false-false-0
regardless of the previous value of the flags; because those pages are equivalent.
If Page17 sends the player a different direction based on the value of the first flag, but neither it nor any of the pages after it look at the second flag, then it will end up silently clearing the second flag; we don't need that data.
Does that algorithm look sane to you?
(I'm also writing a script to convert my files into a Quest gamebook for online play; but I think it would be really nice to output my gamebook as a static text that can be used as a Kindle book, or even a print CYOA. Would that be cool?)