Creating a Save file and being able to Load the file

Good day everyone,

Off and on I've been working with KV on QuestJS features and upgrades, while ironing out issues with my game(s). Having some Save functionality isn't mission critical, but mission handy certainly. I understand Quest has built in Save functionality already, so allow me to skip to the reason for this post:

I'm using Quest 5.7.1 and QuestJS 6.1.3 to convert my game to HTML and then I'm uploading those files to my own webserver and providing direct links to each game. Currently, if you are playing a game in your browser, temporary Internet files are created, but these only store generic information about the webpage information. I tried copying all of them to a different location, deleting my temp files, copying the files back and then trying to load the game...which did not work (formatting was completely messed up). I did some searching through the forums, but I didn't find anything that was the direction I am trying to move in. Feel free to post a link if I missed something though.

I am less concerned with saving progress in a Quest, versus saving Items the player receives (like weapons, armor, etc). I plan on having a separate library for all of those items, so they will exist in every game. I just need a way to have Quest save a list (maybe generate a hash code the player could copy/paste which contains all the info) and then load that for any game they decide to play. This also has to work with QuestJS as well, because if the export breaks the functionality, that doesn't help. LOL

Thanks in advance everyone!

Raist

EDIT:
I just saw this post as well: https://textadventures.co.uk/forum/quest/topic/80ihbe5euuuhifgj5i4dtw/recording-player-activity

Pertex - You are right. With the next version you can call external PHP-scripts. With that you can save information on your own webserver. I provide some scripts to provide e.g. a highscore functionality or to generate walkthroughs from the player's input. Of course, this only works if the player has an online connection, but that should be standard nowadays.

This might provide the answer, unless there is an easier way to do what I'm aiming for.


I thought I was getting close with Saving an object, but maybe I'm not "targeting" the attributes for the objects correctly...I created a function called SaveObject:

<function name="SaveObject" parameters="object"><![CDATA[
    if (object.attribute <> null) {
      foreach (att, object.attribute) {
        attr = NewStringList()
        foreach (o, list) {
          list add (attr, GetString(o, att))
        }
        return (attr)
        msg (ListItem(attr))
      }
      set (object, "save", ListItem(attr))
    }
  ]]></function>

This should grab ALL of the attributes an object has and add them to the StringList attr.

Then I have a command called Export, which calls SaveObject function and passes the parameter of Object:

<command name="export">
    <pattern>export #object#</pattern>
    <unresolved>You cannot save that item.</unresolved>
    <scope>inventory</scope>
    <script>
      if (game.pov = object) {
        PrintCentered ("You cannot Save yourself. Well you can, but not by playing this game.")
      }
      else if (not Got(object)) {
        PrintCentered ("You must be carrying that, in order to Save it.")
      }
      else {
        SaveObject (object)
      }
    </script>
  </command>

So in theory, a player can type export spellbook and all those attributes should be added to a StringList. (for testing purposes, it would be nice to see the results, but I also decided to set an additional attribute (save, string) on the object, equal to the StringList(attr), which would be just as good as displaying it in the game window since I can use the Debugger).

Right now, the save attribute on the object is not being populated. One thing I have not tried yet is creating all of the new Attributes an object can have, adding those to a List and then checking if they are Null or not. If they have a value (whatever it is), save it to the List.

There are a lot of scripts in Quest that would work for this, IF I had the reverse of what they do (set object attribute to value, reverse set value to object attribute, for example).


I think you're wanting to do something like this:

<function name="SaveObject" parameters="object"><![CDATA[
  atts = GetAttributeNames(object, true)
  attr = NewDictionary()
  foreach (att, atts) {
    dictionary add (attr, att, GetAttribute(object,att))
    msg (DictionaryItem(attr, att))
  }
  set (object, "save", attr)
]]></function>

EDITED

The JS code that used to be here threw an error.

After I watch Infinity War, I'll post some JS code (if no one else has by then).


Yep, that is it, KV! Thanks again!

Ah! I was close. So one var is grabbing the attribute names and values and the other is creating the new Dictionary (thinking out loud).

I figured using GetString wasn't going to give me all of the values I wanted (GetString won't grab an Integer I'm assuming).

For my future reference; is there a specific reason you used a Dictionary versus a List? Does it matter or will only Dictionary support this type of data?


That JS stuff throws an error. I didn't notice until just now.


I just went with a dictionary because it seemed easier to retrieve from that, since it has the keys included.


It worked for me. Not online, just locally though.

Enjoy the movie!


Dictionary Attributes are 'input-output' functionality:

item
-> key (input)
-> value (output)

String Dictionary: string value (input) = string value (output)
Object Dictionary: string value (input) = object value (output)
Script Dictionary: string value (input) = script/s value (output)

for an example...

example_object.example_stringdictionary_attribute = NewStringDictionary ()
dictionary add (example_object.example_stringdictionary_attribute, "princess", "The Princess has been taken by a dragon")
dictionary add (example_object.example_stringdictionary_attribute, "dragon", "The dragon can only be killed by the dragon slayer sword")
dictionary add (example_object.example_stringdictionary_attribute, "sword", "An evil wizard has the dragon slayer sword")
dictionary add (example_object.example_stringdictionary_attribute, "wizard", "The evil wizard can be found in his tower")

show menu ("Ask About?", example_object.example_stringdictionary_attribute, false) {
  // princess
  // dragon
  // sword
  // wizard
  msg (StringDictionaryItem (example_object.example_stringdictionary_attribute, result))
  // The Princess has been taken by a dragon! // if princess option chosen
  // or
  // The dragon can only be killed by the dragon slayer sword //  if dragon option chosen
  // or
  // An evil wizard has the dragon slayer sword //  if sword option chosen
  // or
  // The evil wizard can be found in his tower //  if wizard option chosen
}

you can convert some/most (not sure about all) Data Types into String Data Types:

string_variable = ToString (10)
integer_variable = ToInt ("10")

string_variable = ToString (10.123)
integer_variable = ToDouble ("10.123")

object_variable = GetObject ("NAME_OF_OBJECT")
string_variable = object_variable.name
object_variable = GetObject (string_variable)
object_variable = GetObject (object_variable.name)

stringlist_variable = Split ("red;blue;yellow", ";")
string_variable = Join (stringlist_variable, ";")
stringlist_variable = Split (string_variable, ";")


So just a quick update on where things are with this:

I figured out that Quest can handle incorporating an iframe for this project. This led me to a whole new world! (I feel almost like Aladin!) :P

Alright, anyway, using the iframe, and some nifty code from KV (am I driving you nuts with all the emails yet? :\ ), the output from a function can be copy/pasted into the iframe, encrypted to a hash code for easier local Saving. (just copy/paste the hash code to a text file). The goal then is to be able to copy/paste the hash code BACK into Quest to create the Saved item. This will require a custom CreateObject script, but should work in theory.

Of course this means that any player could edit the data before they paste it and create the hash code (I have no desire to dance around with validation for this, sorry). However, this provides an internal way to Save information locally in Quest, without having to save the entire game. Just attach the command(s) for Save/Load to whatever items (limit their scope to inventory only for example) and players handle the rest.

More on this as things get hammered out. Just too exciting not to share at the moment (this could change as soon as something irreparable breaks and the project has to be scrapped though LOL).


Log in to post a reply.

Support

Forums