End Game when Attribute Equals 10

I'm new to Quest, and I haven't learned enough yet to use the code editor.

I'm trying to set an Attribute, then check the attribute each turn to see if it equals 10. If it equals 10, the game ends. If it does not, nothing happens. Throughout the game, certain actions cause the Attribute to increase (Counter +1).

How do I set up such a script, and where should I put it? Under Player? Under Game?


Hi Jador,
The script checking if the attribute has reached 10, should be put under the game object. On the tabs of the game object, you'll see one marked 'scripts'. At the bottom of the page, is a box maked 'turn scripts'. Click 'Add' and paste in/put in something like this: (you will need to give the turn script a name, and tick the box 'enabled when game starts'

if (player.attributename = 10) {
  finish
}

Basically after every turn the player makes in the game the attribute is checked and if true, ie. 10 is reached, it follows the instructions. I assume you will be putting the attribute on the player. How you increase the attribute is of course entirely up to you.
Hope this helps.


(filler for getting my edited post, updated/posted)


the 'bread and butter' of quest's scripting/coding is Attribute (one of three, keeping this simple, types of VARIABLES in quest) and the 'if' Script usage, as, especially when used together, these two SUPER Scripts, let's you do 90% of everything that you want to do within your game. This is not easy to learn for people completely new to coding, and is a huge jump from just learning the basics of using quest's GUI/Editor via going through the 'tutorial' on the quest doc site, but you get the largest 'bang for your buck' in learning Attribute and the 'if' Script usage, again, doing so enables you to do 90% of everything that you want to do in your game. Learning more advanced coding/scripting is diminishing returns, as we're left with only 10% of whatever else you want to do within your game. Learning to work with Functions, iteration, looping, recursion, lists, and dictionaries, is 5% to 9%, leaving you with only 5% to 1% remaining things you might want to put into your game. So, you can see how the diminishing returns happens extremely quickly. The most important thing to learn is Attribute and the 'if' Script usage, as this opens up 90% of everything that you want to do within your game. But, this is not going to be easy, though it's vital if you want to make a decent game.


Quest has 3 (keeping this simple) types of VARIABLES:

VARIABLES:
-> Variables: local/temporary VARIABLES (as soon as the parent/container Element's scripting is done, the Variable is destroyed, so in other words, it only exists within its parent/container Element's scripting, and thus why it's "local", as a Variable can NOT be used anywhere/everyhwere else, whereas an Attribute CAN be used anywhere/everwhere)
-> Attributes: global/permanent VARIABLES (so long as the parent/container Object exists or still exists)
-> Parameters: deals with Functions and Commands: basically a way of 'transfering' data to a Function/Command or from one Function to another Function

a Variable's scripting syntax:

NAME_OF_Variable = VALUE_OR_EXPRESSION

examples:

result = "hi"
handled = false
count = 0

damage = DiceRoll ("3d6") + GetRandomInt (0, 10)

An Attribute's scripting syntax:

NAME_OF_OBJECT.NAME_OF_ATTRIBUTE = VALUE_OR_EXPRESSION
// the 'NAME_OF_OBJECT' has to be an actual existing Object, of course

examples:

game.state = 0 // the special 'game' Game Settings Object is required by quest for your game to work, so it has to exist, lol.
player.alias = "HK" // 'player' has to be an actual existing Object, quest requires there to be a Player Object within a Room Object for your game to work, the 'player' Player Object is the default Player Object, so usually it exists, but you can change it's name, so you may not have a 'player' Player Object, but whatever you re-named it to, instead, and thus you'd use that new name instead of 'player'.
player.strength = 100
orc.dead = false // 'orc' has to be an actual existing Object
katana.damage = 50 // 'katana' has to be an actual existing Object
player.weapon = katana // 'katana' (and of course 'player' too) has to be an actual existing Object

player.damage = player.weapon.damage + player.weapon.damage * player.strength / 100
// conceptually (math's 'order of operations' apply):
// player.damage = katana.damage + katana.damage * player.strength / 100
// player.damage = 50 + 50 * 100 / 100
// player.damage = 50 + (50 * 1 or 5000 / 100) // depends on whether the code's order of operations is read from left to right or right to left (I'm not sure which is it, and am too lazy --- and actually not sure how --- to check it, lol)
// player.damage = 50 + (50)
// player.damage = 100


besides learning the quest's scripting syntax, the other hard part is to train your brain to think in terms of programming/'if' logic and design, which is not easy, it takes years and may programming classes (lol) to learn various programming designs and logic.


here's a link/guide on using these two super scripts, it's a bit more code focused and technical, but I do show how to do this stuff via the GUI/Editor as well within it:

http://textadventures.co.uk/forum/samples/topic/5559/attributes-and-if-script-guide-by-hk (you can scroll down to the 'two super script' section, but I'd recommend you look at the top part too, as it gives some of the basics of understanding coding and of quest's code structure)

The two SUPER scripts:

  1. Attribute (data) usage: run as script -> add new script -> 'variables' section/category -> 'set a variable or attribute' Script -> set variable NAME_OF_OBJECT.NAME_OF_ATTRIBUTE = [EXPRESSION] VALUE_OR_EXPRESSION
  2. the 'if' Script (actions/events/behavior) usage: run as script -> add new script -> 'scripts' section/category -> 'if' Script -> if [EXPRESSION] VALUE_OR_EXPRESSION

ask if you got any questions or need any help with anything


design logic:

checking (the 'if' Script) an Attribute, ca be done 3 methods/wheres/whens:

  1. specific checking within a specific location/moment: NOT constantly checking though
  2. Turnscripts/Timers (local:specific rooms, or global: any/every room): constantly checking
  3. the special 'changedNAME_OF_ATTRIBUTE' Script Attribute: checking upon the Attribute's Value changing, its scripting is activated. (internally, it has to be constantly checking, for it to know when the Attribute's Value changes)

also, here's a step by step walkthrough demo/sample game that you create, teaching you Attribute usage:

http://textadventures.co.uk/forum/quest/topic/5387/i-really-need-help#37375

it doesn't get into the 'if' Script Attribute usage though


here's an example game (of/for/on your OP topic) for you:

  1. (hopefully you can/have download/ed and install/ed the quest desktop/off-line version onto your computer)
  2. create a new 'Text Adventure' game
  3. name it whatever you want and save it somewhere you can find it (such as onto your desktop)
  4. close out of it
  5. right click on it (your newly created game file: 'xxx.aslx'), and choose to open it up with a text editor software (notepad, wordpad, Apple: text editor, notepad++, etc)

what you're seeing is your entire game code (in this case, it's the/a default new game code, of the english language version of quest), which will hopefully look something like this (not sure if Pixie's current version changes how it looks, as I'm using an older version of quest):

<asl version="550">
  
  <include ref="English.aslx" />
  <include ref="Core.aslx" />

  <game name="example_new_game">

    <gameid>SOME_RANDOMLY_GENERATED_HASH_STRING</gameid>
    <version>1.0</version>
    <firstpublished>2017</firstpublished>

  </game>

  <object name="room">

    <inherit name="editor_room" />

    <object name="player">

      <inherit name="editor_object" />
      <inherit name="editor_player" />

    </object>

  </object>

</asl>

the GAME OBJECT is the 'asl' tag block:

<asl version="550"> <!-- This is the beginning 'asl' tag, which is also known as its signature/header, as it often has special Attributes within it for the tag block itself -->

  <!-- YOUR ENTIRE MASS OF YOUR GAME CODE/CONTENT MUST BE HERE WITHIN THE/THIS 'ASL' TAG BLOCK -->

</asl> <!-- This is the ending 'asl' tag (make such you got the '/' in it and in the right place) -->

about the quest version:

the current version of quest is v570 (or is it v580?, meh), but v550, v560, and v570 will all work with the current version of quest.
to see your quest version, in the GUI/Editor, at the menu bar at the top, click either the 'help -> about quest' or 'about', you'll see some long version, for example: quest version 5.7.8.344838293829832983, you only care about the 2 leftmost digits (5.7.x.xxx), and the 3rd leftmost digit (x.x.8.xx) doesn't matter, as you use '0' for it, and that's your 3 digit version number: 570 (from 5.7.8.xxx):

<asl version="570">
</asl>

the default (english language version) quest engine library (code) files:

<asl version="550">

  <include ref="English.aslx" />
  <include ref="Core.aslx" />

</asl>

about library files:

the library file name+extension (same as a game file's): xxx.aslx

the library files have to be in the same location/folder as your game file (xxx.aslx), in order for your game file to be able to find and use them

<library>
  <!-- code -->
</library>

a library file is just code, which is added to and used with/for your game, think of it as like a 'mod, patch, and/or xpac', it can be as simple as adding a single Object to your game, or as complex as being an engine file, yes, quest is powerful, it's made up of library files, so you can create your own unique quest engine, if you're a good programmer and you know quest's code well.

Example of (one of) the most simple type(s) of library file(s):

example_dragon_library_file.aslx

<library>

  <object name="dragon">
    <inherit name="editor_object" />
  </object>

</library>

and it being added to a game file:

example_game_file.aslx

<asl version="550">
  
  <include ref="English.aslx" />
  <include ref="Core.aslx" />

  <!--
  -----------------------------------------------------------------------------------------------------------------------------------------------------------------------

  PUT ALL LIBRARY FILE REFERENCES HERE (under the default engine library file reference tag lines and above the 'game' Game Settings Object tag block):
  -->

  <included ref="example_dragon_library_file.aslx" />

  <!--
  --------------------------------------------------------------------------------------------------------------------------------------
  -->

  <game name="example_new_game">

    <gameid>SOME_RANDOMLY_GENERATED_HASH_STRING</gameid>
    <version>1.0</version>
    <firstpublished>2017</firstpublished>

  </game>

  <object name="room">

    <inherit name="editor_room" />

    <object name="player">

      <inherit name="editor_object" />
      <inherit name="editor_player" />

    </object>

  </object>

</asl>

which is the exact same as if you just did this (as this is what is actually done by the programming):

(when the game is run, it must first be: built-up/'loaded'/'initialized', it first adds the library files' code to the game, from top to bottom, and then it adds the rest of the code within the game file itself to the game. So this is why the engine library files have to be at the top and any custom library files below them, but above the 'game' Game Settings Object --- to be safe anyways, and the order of library files matter, also you have to worry about any compatibility issues, on top of the correct order of library files, if you ever worked with 'mods' in games, you're aware of compatibility issues with quest library files, lol)

example_game_file.aslx

<asl version="550">

  <include ref="English.aslx" />
  <include ref="Core.aslx" />

  <game name="example_new_game">

    <gameid>SOME_RANDOMLY_GENERATED_HASH_STRING</gameid>
    <version>1.0</version>
    <firstpublished>2017</firstpublished>

  </game>

  <object name="room">

    <inherit name="editor_room" />

    <object name="player">

      <inherit name="editor_object" />
      <inherit name="editor_player" />

    </object>

  </object>

  <object name="dragon">

    <inherit name="editor_object" />

  </object>

</asl>

anyways... back to the default new game file:

next, after the library files, is a special Object, the 'game' Game Settings Object:

this special 'game' Game Settings Object (NOT to be confused with the actual 'asl' GAME OBJECT itself), enables/has global/game-wide controls/settings/attributes, the 'start' Script Attribute (this is the first thing that is done when the game starts: good for, examples: character creation, game introduction, etc etc etc), and other various like-settings (author, first published, version --- version history, category, description, difficulty, cruelty, sub-title, etc) info for a person to look at to see if they're interested in playing your game or not, online.

the 'game' Game Settings Object tag block in code is what you see as the 'game' Game Settings Object in the GUI/Editor:

GUI/Editor's left side's 'tree of stuff':

OBJECTS
-> Game -> (after clicking/highlight it) on right side: its various tabs (and its selected tab page): setup, scripts, etc etc, attributes
->-> Verbs
->-> Commands
-> room
->-> player
Functions
Timers
Advanced
-> Libraries
-> Object Types
-> JS
.
.
.
Filter -> Show Library Elements -> (toggle on/off)

<asl version="550">

  <include ref="English.aslx" />
  <include ref="Core.aslx" />

  <game name="NAME_OF_YOUR_GAME">

    <!--
    These Attributes are for being shown information online (using quest's servers/site), for people to know about your game, in whether they want to play it or not:
    -->

    <author>NAME_OF_YOU_THE_AUTHOR/CREATOR/OWNER_OF_THE_GAME</author>
    <version>YOUR_VERSION_HISTORY_AS_A_DECIMAL_NUMBER</version>
    <firstpublished>YEAR_THAT_YOU_CREATED/PUBLISHED_YOUR_GAME</firstplished>
    <category>CATEGORY_OF_YOUR_GAME</category
    <subtitle>SUBTITLE_FOR_YOUR_GAME</subtitle>
    <description>DESCRIPTION_FOR_YOUR_GAME</description>
    <!-- etc etc etc Attributes -->

    <!--
    the 'start' Script Attribute (this is the first thing done when your game starts):
    -->

    <attr name="start" type="script">
      msg ("hi, welcome to my game, I hope you enjoy it!")
    </attr>

    <!-- whatever other various in-game global/game-wide settings/controls/attributes -->

    <!-- whatever custom (self created/added) Attributes -->

  </game>

</asl>

and, after the 'game' Game Settings Object, whatever Elements you want, the default 'room' Room Object and 'player' Player Object, and my various examples of added/created in-game-use Elements, such as: Objects, Exits, Commands, Verbs, Turnscripts, Timers, Object Types):

http://docs.textadventures.co.uk/quest/elements/

<asl version="550">

  <include ref="English.aslx" />
  <include ref="Core.aslx" />

 <game name="example_new_game">

    <gameid>SOME_RANDOMLY_GENERATED_HASH_STRING</gameid>
    <version>1.0</version>
    <firstpublished>2017</firstpublished>

    <attr name="start" type="script">
      greeting_function
      view_info_function (game.pov)
      set_player_alias_function (game.pov)
      player.strength_integer_attribute = input_and_return_strength_function
      view_info_function (game.pov)
      view_info_function (orc_1)
    </attr>

  </game>

  <object name="room">

    <inherit name="editor_room" />

  </object>

  <object name="player">

    <inherit name="editor_object" />
    <inherit name="editor_player" />

    <attr name="parent" type="object">room</attr>

    <attr name="alias" type="string">unknown</attr>
    <attr name="strength_integer_attribute" type="int">-1</attr>

  </object>

  <object name="orc_1">

    <inherit name="editor_object" />

    <attr name="parent" type="object">room</attr>

    <attr name="alias" type="string">orc</attr>

    <attr name="strength_integer_attribute" type="int">25</attr>

  </object>

  <function name="greeting_function">
    msg ("Greetings!")
  </function>

  <function name="view_info_function" parameters="object_parameter">
    msg (object_parameter.name + "'s Alias: " + object_parameter.alias)
    msg (object_parameter.alias + "'s Strength: " + object_parameter.strength_integer_attribute)
  </function>

  <function name="set_player_alias_function" parameters="player_object_parameter">
    msg ("Name?")
    get input {
      player_object_parameter.alias = result
    }
  </function>

  <function name="input_and_return_strength_function" type="int">
    <![CDATA[
      msg ("Strength? (0 to 100)")
      get input {
        if (IsInt (result)) {
          input_integer_variable = ToInt (result)
          if (input_integer_variable < 0 or input_integer_variable > 100) {
            msg ("Wrong input (has to be: 0 to 100), try again")
            input_and_return_strength_function
          } else {
            return (input_integer_variable)
          }
        } else {
          msg ("Wrong input (type in a number), try again")
          input_and_return_strength_function
        }
      }
    ]]>
  </function>

  <!--
  To use the Command below during game play:
  Type into the input/command box during game play, either:
  view player
  view orc_1
  view blahblahblah
  -->

  <command name="view_info_command">
    <pattern>view #object_parameter#</pattern>
    <script>
      view_info_function (object_parameter)
    </script>
    <unresolved>Wrong input, you need to input an Object that exists within the Room you're currently in</unresolved>
  </command>

</asl>
  1. highlight ALL of it and delete ALL of it
  2. highlight, copy, and paste my code below into it, and then save it
  3. close out of it
  4. open it up and study it in the GUI/Editor and try playing/testing/seeing it out too in action

(err, taking a break, tired now after trying to explain the quest coding structure. I'll hopefully get around to coding in a sample game for you for what you want to do, if you've not already figured out how to do it)


What Agon suggests makes sense.

If I were to do it, here is what I would do. Keep in mind, I have no idea what causes the counter to increase, although I would image it is some significant event.

I would:

  1. add an object to the game and call it something like 'countdown'.
  2. Set it as invisible. Just untick the visible box.
  3. Go to the 'attributes' tab of the object 'countdown'.
  4. Add an attribute. Name it 'countdowncounter'. Choose an integer attribute and give it the value of 0.
  5. Click the add change script button.
  6. Here, place an IF script and select 'object attribute equals'.
  7. Choose object 'countdown', attribute 'countdowncounter', and set it equal to 10.
  8. In the THEN part of the script you can add a script to 'Finish Game'. In the code below, I also added a suitable message.
  9. In the ELSE IFs of this same script, select what you want to happen for each significant step toward 10. ie. Repeat step #7, but just set it equal to whatever number you please. In the code below, I set did examples for 1 time and 5 times and 10 times.
  10. For whatever event triggers the counter to increase, add a 'set a variable or attribute' script.
  11. In this script, type your 'object name.object name attribute' in the first box, leave it set as an expression, and type your 'object name.object name attribute +1' in the last box. This example would be: Set variable countdown.countdowncounter = expression countdown.countdowncounter +1

Below is a working example if you want to copy-paste it in a new game to see how it works.

<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="Object attribute equals demo">
    <gameid>e34323e9-3172-4e2e-8b6f-1e41a5c53272</gameid>
    <version>1.0</version>
    <firstpublished>2017</firstpublished>
    <object name="countdown">
      <inherit name="editor_object" />
      <visible type="boolean">false</visible>
      <countdowncounter type="int">0</countdowncounter>
      <changedcountdowncounter type="script">
        if (countdown.countdowncounter = 10) {
          msg ("You have pushed the button of doom too many times! Your world explodes.")
          finish
        }
        else if (countdown.countdowncounter = 5) {
          msg ("I really would stop pushing that button!")
        }
        else if (countdown.countdowncounter = 1) {
          msg ("You have pushed it once.  I wouldn't push it anymore.")
        }
      </changedcountdowncounter>
    </object>
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
    <object name="button">
      <inherit name="editor_object" />
      <push type="script">
        msg ("You push the button.")
        countdown.countdowncounter = countdown.countdowncounter + 1
      </push>
    </object>
  </object>
</asl>

Doctor Agon's solution will work, but a better way is with a change script if yoiu are using the desktop version (you can use them on the web version, but it is a bit more complicated). That way it will only be checked when the attribute changes, not ever turn.

Go to the Attributes tab of the object, and click on the attribute. Then click the "Change script" button above, and you will get a new script attribute. Paste Doctor Agon's code in there.


Wow. This is a lot of information. I haven't gotten into the coding yet, so much of what hegemonkhan and XanMag said isn't quite what I was looking for. Little too advanced for me yet.

Agon's advice was spot on though. Found the Turn Scripts option, and the counter works perfectly now. Thanks!


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

Support

Forums