I 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.
Is 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.