[RESOLVED] What counts as a turn? Turnscripts not running unless explicitly told to.

Main Issue: Turnscripts don't seem to be running unless I explicitly call the RunTurnScripts command somewhere, despite being enabled.

RESOLUTION: A fresh install seems to have fixed the problem, though the root cause of the issue still isn't clear

I know this sounds like a super basic question, and at some level it is, but I'm really confused by what counts as a turn in Quest.

As I (thought I) understood it, a turn is generally supposed to be any command you pass into the game. This is why it is often recommended to have some sort of way to catch unsuccessful turns (i.e. using a notarealturn attribute). I set up such an attribute according to the directions in The Pixie's ClockLib tutorial.

As it stands, however, with the exception of a turnscript which prevents time from advancing on the character creation screen, it seems like none of my turnscripts are running unless I explicitly use RunTurnScripts. This includes the ClockLibTurnScript which is included in ClockLib. They are all enabled when the game begins, so I don't think that that's the issue, but I could be wrong.

There is not a lot yet in the game, as it's still very early in development, but these are the actions which I have tried which fail to advance the turn count: going through exits, speaking to characters, sitting on a couch, the "wait" command which comes with ClockLib. I am using Quest 5.8.0 desktop version, and all my testing has been through the "Play" button in the desktop editor.

Have I misunderstood what a turn is? Or is it possible I've overlooked something in the code? I tried searching the forums to see if this question had been answered before, but couldn't find anything quite right.

EDIT: It is worth mentioning also that they're not throwing any errors, they just don't seem to be doing anything at all.


Have you modified any of the core functions? I know some libraries included modified versions of functions like RunTurnScripts in order to fix issues in the core. But if you use those libraries with a newer version of Quest in which the core stuff works differently, it can create some very odd issues.

Can you share the game? Poking around in the code might reveal some clues.

This is why it is often recommended to have some sort of way to catch unsuccessful turns (i.e. using a notarealturn attribute).

As of Quest 5.8, you can do this using the SuppressTurnscripts() function.

Have I misunderstood what a turn is?

Until Quest 5.7, a turn was an exchange of data between the Quest backend and the Javascript frontend. This could be caused by the player inputting commands, some javascript calling ASLEvent, or a timer triggering. This made turnscripts perfect for things like updating custom status bars, attaching icons to the inventory, or displaying a custom map, because it meant they would be run every time something on screen needs to change.

As of Quest 5.8, a turn is the successful execution of a single command. This means they're better for things like counting turns or the player being poisoned, but are no longer suitable for all the display sync stuff.


Have you modified any of the core functions?

Only insofar as ClockLib does, as that's the only custom library I'm using at the moment.

Can you share the game?

Due to the nature of the game, I don't want to publicly post the whole thing in this forum, if you catch my meaning. I can share the relevant stuff, however, including turnscripts and whatnot. These are just the ones not included in ClockLib, since those can be found on The Pixie's github I linked in the OP.

turn tracker (self explanatory, just a tracker I'm using to test when turns are actually advancing. Currently only moves forward if RunTurnScripts is called, except in the first room where it works as normal if I remove the game.notarealturn = true line in the timeless script.)

if (not game.notarealturn) {
  player.turns = player.turns + 1
}
game.notarealturn = false

timeless (prevents time from advancing in the character creation screen. This is the only script which currently seems to be working as intended.)

if (game.pov.parent = intro) {
  game.notarealturn = True
  SetInc (0)
}

NpcTurnScript (taken from the Making NPCs Patrol tutorial, works as intended as long as RunTurnScripts is called)

foreach (o, AllObjects()) {
  if (HasScript(o, "takeaturn")) {
    do (o, "takeaturn")
  }
}

This is a typical example of the kind of verb that is currently in my game. It's just a standard "sit on couch" thing. Without calling RunTurnScripts, however, they don't run, though it seems to me that they should.

msg ("You sit on the couch and rest for a moment. After a couple minutes you get up.")
RunTurnScripts

The only thing I can think of that I haven't mentioned or tested much yet is that turnscripts seem to work fine in the first room, which is currently used for some character creation and introduction stuff. There is a one-way exit in from the first room which is how the player enters the rest of the game. Could that be affecting the turnscripts somehow? Using the exit there runs this script (I had to include enabling NpcTurnScript because for some reason it was showing in the debug tool as disabled even though it is supposed to be enabled from the start):

player.parent = this.to
DisableTurnScript (timeless)
EnableTurnScript (NpcTurnScript)

Thank you for your help!


The only thing I can think of that I haven't mentioned or tested much yet is that turnscripts seem to work fine in the first room, which is currently used for some character creation and introduction stuff.

If you add this line to the script in the first room:

RemoveObject (NpcTurnScript)

what happens?

(This may seem an odd question. I found that asking it in a more sensible way quickly turned into a wall of text because I'm not sure how much detail you know about how turnscripts work)


Since you didn't specify where to add that, I tried adding that line to the script in a few places. The first was in the room description (setting it to run a script instead of display text, of course). Then I tried running it before entering the room. Then I tried it on the exit to the next screen. Finally, I tried it in the timeless turnscript. As far as I can tell, it didn't do anything in any of those locations.

In case this is what you're getting at, or at least helpful for it: the timeless turnscript is located specifically in the first room. The other ones are under the "Objects" part of the file tree (i.e. not in any rooms). They show up in the turnscripts list in the game tab, however.


In the interest of helping find where things are going screwy, I'm going to post a slightly redacted version of the full code. The only things I'm excluding are a few of the actions that made me reluctant to share this publicly earlier and some dialogue related to that as well. The actions so far only print text, so I doubt that's where the issue is. Additionally, a bunch of empty rooms are getting left out, but they're literally empty except for exits that do nothing special.

I hope this helps!

<!--Saved by Quest 5.8.6836.13983-->
<asl version="580">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <include ref="ClockLib.aslx" />
  <game name="Sharktooth Cove Spa and Resort">
    <gameid>96720655-204a-492b-b45f-fc5727374433</gameid>
    <version>1.0</version>
    <firstpublished>2020</firstpublished>
    <author>Zdarlight</author>
    <gridmap />
    <category>Adult</category>
    <notarealturn type="boolean">false</notarealturn>
    <attr name="feature_advancedscripts" type="boolean">false</attr>
    <statusattributes type="stringdictionary">
      <item>
        <key>clock</key>
        <value>Time: !</value>
      </item>
    </statusattributes>
    <attr name="feature_asktell" type="boolean">false</attr>
    <appendobjectdescription type="boolean">false</appendobjectdescription>
    <start type="script">
      SetTime ("01:06:59")
      game.clock = TimeAsString()
      game_clock.waittime = 10
    </start>
    <unresolvedcommandhandler type="script">
      game.notarealturn = true
      msg (Template("UnrecognisedCommand"))
    </unresolvedcommandhandler>
    <roomenter type="script">
      RunTurnScripts
    </roomenter>
  </game>
  <object name="intro">
    <inherit name="editor_room" />
    <alias>Introduction</alias>
    <usedefaultprefix type="boolean">false</usedefaultprefix>
    <prefix>the</prefix>
    <beforefirstenter type="script">
    </beforefirstenter>
    <description type="string"></description>
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
      <statusattributes type="stringdictionary">
        <item>
          <key>weight</key>
          <value>Weight: ! lbs</value>
        </item>
        <item>
          <key>species</key>
          <value>Species: !</value>
        </item>
        <item>
          <key>alias</key>
          <value>Name: !</value>
        </item>
        <item>
          <key>playerGender</key>
          <value>Gender: !</value>
        </item>
        <item>
          <key>turns</key>
          <value>Turns: !</value>
        </item>
      </statusattributes>
      <turns type="int">0</turns>
      <weight type="int">120</weight>
      <playerGender type="string"></playerGender>
      <species type="string"></species>
      <alias type="string"></alias>
    </object>
    <exit alias="in" to="lobby">
      <inherit name="indirection" />
      <runscript />
      <script type="script">
        player.parent = this.to
        DisableTurnScript (timeless)
        EnableTurnScript (NpcTurnScript)
      </script>
    </exit>
    <turnscript name="timeless">
      <enabled />
      <script>
        if (game.pov.parent = intro) {
          SetInc (0)
          game.notarealturn = True
        }
      </script>
    </turnscript>
    <object name="Nametag">
      <inherit name="editor_object" />
      <feature_usegive />
      <displayverbs type="stringlist">
        <value>Look at</value>
        <value>Use</value>
      </displayverbs>
      <look>Use this to set your name.</look>
      <use type="script">
        msg ("Input name...")
        get input {
          player.alias = result
          msg ("Name set to " + player.alias)
        }
      </use>
    </object>
    <object name="Species Changer">
      <inherit name="editor_object" />
      <look>Use this to set your species.</look>
      <displayverbs type="stringlist">
        <value>Look at</value>
        <value>Use</value>
      </displayverbs>
      <feature_usegive />
      <use type="script">
        msg ("Input species...")
        get input {
          player.species = result
          msg ("Player species set to " + player.species)
        }
      </use>
    </object>
    <object name="Gender Changer">
      <inherit name="editor_object" />
      <feature_usegive />
      <displayverbs type="stringlist">
        <value>Look at</value>
        <value>Use</value>
      </displayverbs>
      <look>Use this to set your gender.</look>
      <use type="script">
        options = NewStringList()
        list add (options, "Male")
        list add (options, "Female")
        list add (options, "Non-Binary")
        ShowMenu ("Select Gender...", options, false) {
          switch (result) {
            case ("Male") {
              player.playerGender = "Male"
            }
            case ("Female") {
              player.playerGender = "Female"
            }
            case ("Non-Binary") {
              player.playerGender = "Non-Binary"
            }
          }
        }
      </use>
    </object>
  </object>
  <object name="lobby">
    <inherit name="editor_room" />
    <usedefaultprefix type="boolean">false</usedefaultprefix>
    <prefix>the</prefix>
    <description><![CDATA[The lobby is neat and clean. The walls are painted white and the furniture tends to be in various shades of light blue. During the day, the room is filled with bright sunlight flowing in from tall windows.<br/><br/>To the north you see a hallway leading toward the beach. To the east you see a hallway leading toward the guests' rooms. To the west you see the buffet.]]></description>
    <firstenter type="script">
    </firstenter>
    <beforefirstenter type="script">
    </beforefirstenter>
    <exit alias="east" to="eHall1">
      <inherit name="eastdirection" />
      <runscript type="boolean">false</runscript>
      <script type="script">
        player.parent = this.to
      </script>
    </exit>
    <exit alias="west" to="buffet">
      <inherit name="westdirection" />
      <runscript type="boolean">false</runscript>
      <script type="script">
      </script>
    </exit>
    <exit alias="north" to="nHall1">
      <inherit name="northdirection" />
      <attr name="grid_length" type="int">3</attr>
      <runscript type="boolean">false</runscript>
      <script type="script">
      </script>
    </exit>
    <object name="concierge">
      <inherit name="editor_object" />
      <inherit name="male" />
      <look>An unnaturally-perfect looking red fox in a perfectly tailored suit. He never seems to move from behind the desk.</look>
      <speak type="script">
        options = NewStringList()
        list add (options, "Where am I?")
        list add (options, "Who are you?")
        list add (options, "I am ready to check out.")
        ShowMenu ("\"Welcome to the Sharktooth Cove Spa and Resort. How can I help you?\"", options, true) {
          switch (result) {
            case ("Where am I?") {
              msg ("\"You are in the wonder Sharktooth Cove Spa and Resort. Enjoy our many wonderful amenities, including the all-you-can-eat buffet and the pool. This is a very social place, so please feel free to interact with your fellow guests.\"")
            }
            case ("Who are you?") {
              msg ("\"I am the concierge. It is my job to watch over the resort and ensure our guests are happy and the property is properly maintained. Speak to me if you have any questions, or if you are ready to check out.\"")
            }
            case ("I am ready to check out.") {
              msg ("\"Excellent. Unfortunately this feature has not fully been implemented yet. \"")
            }
          }
        }
      </speak>
    </object>
    <object name="couch">
      <inherit name="editor_object" />
      <look>A firm, light-blue couch. It looks nice, but not overly comfortable.</look>
      <sit type="script">
        msg ("You sit on the couch and rest for a moment. After a couple minutes you get up.")
        RunTurnScripts
      </sit>
    </object>
  </object>
  <object name="eHall1">
    <inherit name="editor_room" />
    <alias>eastern hallway</alias>
    <usedefaultprefix type="boolean">false</usedefaultprefix>
    <prefix>the</prefix>
    <description>The hallway is clean and well lit with polished hardwood floors. To the north is your room. To the south is Zdar's room. To the west is the lobby. More bedrooms are to the east.</description>
    <exit alias="west" to="lobby">
      <inherit name="westdirection" />
    </exit>
    <exit alias="east" to="eHall2">
      <inherit name="eastdirection" />
    </exit>
    <exit alias="north" to="playerBed">
      <inherit name="northdirection" />
    </exit>
    <exit alias="south" to="zdarBed">
      <inherit name="southdirection" />
    </exit>
  </object>
  <object name="zdarBed">
    <inherit name="editor_room" />
    <alias>bedroom</alias>
    <usedefaultprefix type="boolean">false</usedefaultprefix>
    <prefix>Zdar's</prefix>
    <exit alias="north" to="eHall1">
      <inherit name="northdirection" />
    </exit>
    <exit alias="in" to="zdarBath">
      <inherit name="indirection" />
    </exit>
    <object name="Zdar">
      <inherit name="editor_object" />
      <inherit name="namedmale" />
      <look>A porcupine with brown skin and cream-colored quills. He's wearing an unbuttoned lavender shirt and dark blue shorts.</look>
      <weight type="int">250</weight>
      <species>porcupine</species>
      <feature_startscript />
      <feature_usegive />
      <speak>there will be dialogue here</speak>
      <attr name="_initialise_" type="script"><![CDATA[
        oldroom = this.parent
        this.takeaturn => {
          if (this.eaten = False) {
            if (not IsAfterDaily("1:00") or IsAfterDaily("19:00")) {
              this.parent = bar
            }
            else if (IsAfterDaily("1:00") and not IsAfterDaily("9:00")) {
              this.parent = zdarBed
            }
            else if (IsAfterDaily("9:00") and not IsAfterDaily("10:00")) {
              this.parent = buffet
            }
            else if (IsAfterDaily("10:00") and not IsAfterDaily("11:00")) {
              this.parent = rileyBed
            }
            else if (IsAfterDaily("11:00") and not IsAfterDaily("14:00")) {
              this.parent = beach
            }
            else if (IsAfterDaily("14:00") and not IsAfterDaily("15:00")) {
              this.parent = buffet
            }
            else if (IsAfterDaily("15:00") and not IsAfterDaily("16:00")) {
              this.parent = zdarBed
            }
            else if (IsAfterDaily("16:00") and not IsAfterDaily("18:00")) {
              this.parent = sauna
            }
            else if (IsAfterDaily("18:00") and not IsAfterDaily("19:00")) {
              this.parent = buffet
            }
          }
        }
        if (not oldroom = this.parent) {
          PrintIfHere (oldroom, "Zdar leaves the room")
          PrintIfHere (this.parent, "Zdar enters the room")
        }
      ]]></attr>
    </object>
  </object>
  <turnscript name="turn tracker">
    <enabled />
    <script>
      if (not game.notarealturn) {
        player.turns = player.turns + 1
      }
      game.notarealturn = false
    </script>
  </turnscript>
  <turnscript name="NpcTurnScript">
    <enabled />
    <script>
      foreach (o, AllObjects()) {
        if (HasScript(o, "takeaturn")) {
          do (o, "takeaturn")
        }
      }
    </script>
  </turnscript>
  <function name="PrintIfHere" parameters="room, s">
    if (game.pov.parent = room) {
      msg (s)
    }
  </function>
</asl>

I can't see any problems here, it certainly looks like turnscripts should be running.

I can't replicate this problem myself, so it's hard to work out what could be causing it.
I assume that it's the clock failing to change that lets you know they aren't running?

This one has me really confused now.


Yeah, the clock not changing and the turn counter not incrementing except when RunTurnScripts is called are the main things that are indicating to me that turnscripts aren't running.

I just tried something that I should have tried earlier: a fresh install. That seems to have fixed it, but I'm not sure what caused the issue in the first place now...

Thanks for your help and doing what you could to try to get this fixed!


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums