Gamebook / TA hybrid
mrangel
12 Jul 2019, 16:12I was looking over the Quest GamebookCore to answer somebody else's question, and an idea popped into my head.
Would it be possible to combine gamebook and text adventure, to make a hybrid format? Including all the types and functions from both core sets. All the gamebook page types would inherit a new type gamebookpage
to make them identifiable.
Then you'd give the player object the changedparent
script from the Text Adventure mode, but change a couple of functions like so:
<function name="OnEnterRoom" parameters="oldRoom">
<![CDATA[
game.displayroomdescriptiononstart = false
if (IsDefined("oldRoom")) {
if (oldRoom <> null) {
if (game.clearscreenonroomenter) {
ClearScreen
if (HasString (game, "currentexitmessage")) {
msg(game.currentexitmessage)
game.currentexitmessage = null
}
}
if (HasScript(oldRoom, "onexit")) {
do (oldRoom, "onexit")
}
}
}
on ready {
if (DoesInherit (game.pov.parent, "gamebookpage")) {
game.gamebookdisplay = true
DoPage (game.pov.parent)
}
else {
game.gamebookdisplay = false
if ((not GetBoolean(game.pov.parent, "visited")) and HasScript(game.pov.parent, "beforefirstenter")) {
do (game.pov.parent, "beforefirstenter")
}
on ready {
if (HasScript(game.pov.parent, "beforeenter")) {
do (game.pov.parent, "beforeenter")
}
on ready {
if (game.gridmap) {
Grid_CalculateMapCoordinates (game.pov.parent, game.pov)
Grid_DrawPlayerInRoom (game.pov.parent)
}
if (IsDefined("oldRoom")) {
if (oldRoom <> null and game.changeroom_newline and not game.command_newline) {
msg ("")
}
}
JS.updateLocation(CapFirst(GetDisplayName(game.pov.parent)))
roomFrameExists = false
if (HasString(game.pov.parent, "picture")) {
if (LengthOf(game.pov.parent.picture) > 0) {
roomFrameExists = true
SetFramePicture(game.pov.parent.picture)
}
}
if (game.clearframe and not roomFrameExists) {
ClearFramePicture
}
if (game.showdescriptiononenter) {
ShowRoomDescription
}
if (HasScript( game, "roomenter")) {
do (game, "roomenter")
}
on ready {
if ((not GetBoolean(game.pov.parent, "visited")) and HasScript(game.pov.parent, "firstenter")) {
do (game.pov.parent, "firstenter")
}
on ready {
if (HasScript(game.pov.parent, "enter")) {
do (game.pov.parent, "enter")
}
}
set (game.pov.parent, "visited", true)
}
}
}
}
}
]]>
</function>
<function name="InitInterface">
<![CDATA[
if (GetBoolean (game, "gamebookdisplay")) {
JS.uiHide ("#txtCommandDiv,#location,#gamePanel,#gridPanel")
JS.panesVisible (false)
}
else {
// contents of current TA InitInterface here
}
]]>
</function>
<function name="HandleCommand" parameters="command, metadata">
<![CDATA[
handled = false
// Moved to the beginning so you can do transcript comments while a menu is visible
if (StartsWith (command, "*")) {
// Modified by KV to bypass turn scripts and turn counts, and to print "Noted."
game.suppressturnscripts = true
msg ("")
msg (SafeXML (command))
msg("Noted.")
// Added for Quest 5.8 - KV
FinishTurn
handled = true
}
if (game.menucallback <> null) {
if (HandleMenuTextResponse(command)) {
handled = true
}
else {
if (game.menuallowcancel and not handled) {
ClearMenu
}
else {
handled = true
}
}
}
if (HasAttribute(game.pov.parent, "options") and not handled) {
if (DictionaryContains(game.pov.parent.options, command)) {
if (not GetBoolean (game, "clearlastpage")) {
optiontext = StringDictionaryItem(player.parent.options, command)
msg ("<b>" + optiontext + "</b>")
msg ("")
}
JS.disableAllCommandLinks()
game.pov.parent = GetObject(command)
handled = true
}
}
if (not handled) {
StartTurnOutputSection
shownlink = false
if (game.echocommand) {
if (metadata <> null and game.enablehyperlinks and game.echohyperlinks) {
foreach (key, metadata) {
if (EndsWith(command, key)) {
objectname = StringDictionaryItem(metadata, key)
object = GetObject(objectname)
if (object <> null) {
msg ("")
msg ("> " + Left(command, LengthOf(command) - LengthOf(key)) + "{object:" + object.name + "}" )
shownlink = true
}
}
}
}
if (not shownlink) {
msg ("")
OutputTextRaw ("> " + SafeXML(command))
}
}
if (game.command_newline) {
msg ("")
}
game.pov.commandmetadata = metadata
if (game.multiplecommands){
commands = Split(command, ".")
if (ListCount(commands) = 1) {
game.pov.commandqueue = null
HandleSingleCommand (Trim(command))
}
else {
game.pov.commandqueue = commands
HandleNextCommandQueueItem
}
}
else {
game.pov.commandqueue = null
HandleSingleCommand (Trim(command))
}
}
]]>
</function>
You'd also want to make a script game.changedgamebookdisplay
which just calls InitInterface()
.
Not sure if there's other elements that would need showing/hiding. But I think I've seen a few people who would have liked the ability to mix and match gamebook and text adventure sections in the same game :p
This is just off the top of my head, but it's been bouncing around in my mind for a while. Would this be a useful library? Overrides a couple of core functions, and allows you to include gamebook sections within a text adventure.

Zesc
12 Jul 2019, 20:24Is it possible? Yes.
Is it possible using your code example? To be humble, i only skimmed it.
The thing is: gamebook mode is infact just the inferior cousin of TA so far (speaking of first hand experience with it's limitations; there are literally only three kinds of objects game
, player
and page
) and everything you can do in CYOA can be done with parser-based games, probably even better.
There is a library to hide the parser, inventory and the rest of the TA UI, but i think you already know that. So you only have to en-/disable it in time.
Also, i think there has been mixed CYOA/TA games on this site already, but i can't remember a game title right now.