saving the game curiosty

I am curious if there is a command that can detect when the player saves the game. For example, I have an npc I want to tell the player that they have successfully saved the game. Like maybe the command would be like if game.saved = true then print message: Congrats you saved the game. I am also wondering if I can make an area or specific place where the player can't save the game. I am not quite sure what that code would look like and I would like some help on this.


Hello,

(You opened a can of worms!)

You can create your own save command. Here's one of mine:


game.notarealturn = true
JS.playerCheck ()
SetTimeout (2) {
  JS.playerCheck ()
  SetTimeout (2) {
    JS.eval ("addText (\"Save time: \"+Date()+\"<br/>\");")
    if (not game.online) {
      request (RequestSave, "")
    }
    else {
      JS.setInterfaceString ("TypeHereLabel", "Save in progress...")
      msg ("If you are playing online, your game may behave erratically when you resume play.<br/>This game behaves best when played using the desktop version of Quest 5.7.1.<br/>")
      JS.scrollToEnd ()
      JS.saveGame ()
      JS.afterSave ()
    }
  }
}

The game saves differently when playing online.

Looking through Quest's source code, I found the JS that checked whether the player was online, and I used that to make this function:

//This checks for the web player, setting game.online to true or false
var bool = false;
function playerCheck() {
  if (webPlayer) {
    //addText("<br/>[Game running in Online player.]");
    bool = true;
    ASLEvent("setOnline", bool);
  }
  else {
    //addText("<br/>[Game running in Desktop player.]");
    bool = false;
    ASLEvent("setOnline", bool);
  }
}

...and I created a function in the game to handle that ASLEvent:

  <function name="setOnline" parameters="bool">
    game.online = bool
    switch (bool) {
      case ("true") {
        game.online = true
      }
      case ("false") {
        game.online = false
      }
      default {
        error ("Error checking for online player.")
      }
    }
  </function>

See it in action:

http://textadventures.co.uk/games/view/jymfhimg00c5cvrdqna7xa/pixies-quest


PS

I can post a simple way to do it.

This is the coolest method I could conjure up while collaborating on the Pixie game.

NOTE: If you enter the command SAVE (instead of clicking on 'Save') when playing online, Quest doesn't save any of the game's text by default at the moment. It's like the screen has been cleared when you load a save. This fixes that, too. Hence all the extra functions.


This is the simplest way I can conjure up that still checks for the web player:

<!--Saved by Quest 5.7.6404.15496-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="Saving Fancily">
    <gameid>4f0614a3-267e-4afe-b43c-5508ef2b0ac9</gameid>
    <version>1.3</version>
    <firstpublished>2017</firstpublished>
  </game>
  <command name="save">
    <pattern type="string">^save$</pattern>
    <script>
      JS.eval ("if (webPlayer){alert('Playing online');saveGame();}else{alert('Playing in the desktop version');ASLEvent('SaveFunction', '');};")
    </script>
  </command>
  <object name="room">
    <inherit name="editor_room" />
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
  </object>
  <function name="SaveFunction" parameters="param">
    request (RequestSave, "")
  </function>
</asl>

You could change alert('Playing online') to addTextAndScroll('<br/>Insert your message here<br/>'), or just change the alert message if you like the alert. The same goes for alert('Playing in the desktop version').


(ignore me, responding to the first post before I saw the second)


So, let's say the player uses this command and I want an NPC to notice this action. Say I want to do some sort of forth wall joke about saving the game. They press the command to save the game. Then through another command could load said game. Is it possible for an npc to notice this. Where an object or character would check if the player has saved or not?


//After the other script (Ralph is my NPC, of course.)
if (Ralph.parent = player.parent) {
  msg ("{random:The game has been saved, and that villainous scoundrel, Murphy, is still out there somewhere...:'Oh, hell!' declares Ralph. 'Are we wussing out, or are we about to mess something up?'}")
}
else {
  msg ("The game has been saved, and that villainous scoundrel, Murphy, is still out there somewhere...")
}

mrangel,

Sorry about that! I realized how disarrayed everything was once I posted that first method. (You've taught me a lot about JS since then, sir. Hence my second code. (Was yours more elegant? (Don't lie to make me feel good, either!)))


would the player be able to load said save via the in-game command as well?


Well, when you save a game online, you can click "Play (resume)' or 'Restart' from the game's page.

When you in the desktop, it creates a save file, which you open to resume play.

I don't know of a command, which doesn't mean it doesn't exist...

...but this saving method makes it so your save file works correctly, whether playing online or offline.


Now you've got me trying to work out how, following the save function, you could have the NPC say something just after saving, but something different when you load the saved game :p First I was thinking about using the UI initialisation script to set something up. But then I thought that there's probably an easier way. Because JS variables aren't saved/restored… something like…

JS.eval("hasJustSaved = true; setTimeout(function() {hasJustSaved=false;}, 5000);")
// commands to actually save the game go here
OutputTextNoBr("Ralph turns to you and says: ")
msg("<script>addText(hasJustSaved ? '“Well, are you ready to go then?”' : '“Well, are we... Wait, didn’t I already say that? Did you get yourself killed again?”');</script>")
msg("")

(yes, I know that's horrible and has significant flaws even if it works. It was a first guess at how it might be done)


K.V.
Well, when you save a game online, you can click "Play (resume)' or 'Restart' from the game's page.

When you in the desktop, it creates a save file, which you open to resume play.

I don't know of a command, which doesn't mean it doesn't exist...

...but this saving method makes it so your save file works correctly, whether playing online or offline.


Me:
Oh, okay so it's just a custom command that works like normal saving but it's a way for the npcs to recognize it. Makes enough sense. Also, I was curious if there can be a custom 'restart' command. In short, I was thinking of putting achievements in my game but I know when a player starts a new game or loads back into the game they resumed the achievement wouldn't be there. Is there a way to fix this issue so that the achievement is a permanent unlocked thing for the player?


I was thinking of putting achievements in my game but I know when a player starts a new game or loads back into the game they resumed the achievement wouldn't be there. Is there a way to fix this issue so that the achievement is a permanent unlocked thing for the player?

I've thought about that before. Playing online, you could use cookies or localStorage to save data outside of the individual game session. No idea if that would work with the desktop version or not, I never got around to testing it.


mrangel,

Ha! I tried the same thing, and the amount of time it takes to save the game varies, so the timers always ended up frustrating me.

The only way I came up with that worked involved changing the saveGameResponse function, and I wasn't sure I should be fooling around with that.

I searched for an attribute or variable that was set by default after loading a saved game, but I couldn't find anything.


Anthony,

Maybe you could:

  • Set up the achievements as attributes
  • Set those attributes to something else after saving the game
  • Run a user initialization script that does something if the attributes are whatever you want them to be after saving.

There is no RESTART command (which is something mrangel and I have also worked on). You can create a RESTART command that works in the online player, but the only ways I can find to restart the desktop player is by pressing CTRL+R or using the menu.

Also, the restart will start whatever game you're playing from the beginning. If it's the original game, it would start from the very beginning. BUT, if was a saved file and you just saved before restarting, it would start where you expected it to (I think -- as long as you save the file over the old save file AND that's the one you're playing from).


The timer isn't actually necessary, I think.
You don't really want a <script> element. What you want is a div with an onready function that changes its content. That can change the message either way, and then clear the variable afterwards. (I think that onready function will execute every time it is reloaded from the saved text buffer; so you probably want it to check if it's at the end of divOutput too. If you're really crafty, you could generate a unique ID each time the game saves, and track how many times each one has been loaded from using cookies :p)


This works:

<!--Saved by Quest 5.7.6404.15496-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="Saving Fancily">
    <gameid>4f0614a3-267e-4afe-b43c-5508ef2b0ac9</gameid>
    <version>1.3</version>
    <firstpublished>2017</firstpublished>
    <feature_advancedscripts />
    <inituserinterface type="script">
      if (HasAttribute(game, "saved")) {
        JS.alert ("You have loaded a saved game!")
      }
    </inituserinterface>
  </game>
  <command name="save">
    <pattern type="string">^save$</pattern>
    <script>
      JS.eval ("if (webPlayer){alert('Playing online');saveGame();}else{alert('Playing in the desktop version');ASLEvent('SaveFunction', '');};")
      game.saved = true
    </script>
  </command>
  <object name="room">
    <inherit name="editor_room" />
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
  </object>
  <function name="SaveFunction" parameters="param">
    request (RequestSave, "")
  </function>
</asl>

This also works (instead of the alert, but not without the SetTimeout):

    <inituserinterface type="script">
      if (HasAttribute(game, "saved")) {
        SetTimeout(1) msg ("You have loaded a saved game!")
      }
    </inituserinterface>

Log in to post a reply.

Support

Forums